17ff866d286cf4df0948feeffa6e67848740e64ebSudheer Shanka/*
27ff866d286cf4df0948feeffa6e67848740e64ebSudheer Shanka * Copyright (C) 2016 The Android Open Source Project
37ff866d286cf4df0948feeffa6e67848740e64ebSudheer Shanka *
47ff866d286cf4df0948feeffa6e67848740e64ebSudheer Shanka * Licensed under the Apache License, Version 2.0 (the "License");
57ff866d286cf4df0948feeffa6e67848740e64ebSudheer Shanka * you may not use this file except in compliance with the License.
67ff866d286cf4df0948feeffa6e67848740e64ebSudheer Shanka * You may obtain a copy of the License at
77ff866d286cf4df0948feeffa6e67848740e64ebSudheer Shanka *
87ff866d286cf4df0948feeffa6e67848740e64ebSudheer Shanka *      http://www.apache.org/licenses/LICENSE-2.0
97ff866d286cf4df0948feeffa6e67848740e64ebSudheer Shanka *
107ff866d286cf4df0948feeffa6e67848740e64ebSudheer Shanka * Unless required by applicable law or agreed to in writing, software
117ff866d286cf4df0948feeffa6e67848740e64ebSudheer Shanka * distributed under the License is distributed on an "AS IS" BASIS,
127ff866d286cf4df0948feeffa6e67848740e64ebSudheer Shanka * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
137ff866d286cf4df0948feeffa6e67848740e64ebSudheer Shanka * See the License for the specific language governing permissions and
147ff866d286cf4df0948feeffa6e67848740e64ebSudheer Shanka * limitations under the License
157ff866d286cf4df0948feeffa6e67848740e64ebSudheer Shanka */
167ff866d286cf4df0948feeffa6e67848740e64ebSudheer Shanka
177ff866d286cf4df0948feeffa6e67848740e64ebSudheer Shankapackage com.android.settingslib;
187ff866d286cf4df0948feeffa6e67848740e64ebSudheer Shanka
197ff866d286cf4df0948feeffa6e67848740e64ebSudheer Shankaimport android.content.Context;
207ff866d286cf4df0948feeffa6e67848740e64ebSudheer Shankaimport android.content.res.TypedArray;
217ff866d286cf4df0948feeffa6e67848740e64ebSudheer Shankaimport android.graphics.drawable.Drawable;
227ff866d286cf4df0948feeffa6e67848740e64ebSudheer Shankaimport android.os.UserHandle;
237ff866d286cf4df0948feeffa6e67848740e64ebSudheer Shankaimport android.support.v7.preference.Preference;
247ff866d286cf4df0948feeffa6e67848740e64ebSudheer Shankaimport android.support.v7.preference.PreferenceViewHolder;
25fdfc88faef4d722b7ae09d8acd7a57a511b3eb72Fan Zhangimport android.text.TextUtils;
267ff866d286cf4df0948feeffa6e67848740e64ebSudheer Shankaimport android.util.AttributeSet;
277ff866d286cf4df0948feeffa6e67848740e64ebSudheer Shankaimport android.util.TypedValue;
28145017303494e77026bd99ec41476f6f53225d95Sudheer Shankaimport android.view.View;
297ff866d286cf4df0948feeffa6e67848740e64ebSudheer Shankaimport android.widget.TextView;
307ff866d286cf4df0948feeffa6e67848740e64ebSudheer Shanka
317ff866d286cf4df0948feeffa6e67848740e64ebSudheer Shankaimport static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
327ff866d286cf4df0948feeffa6e67848740e64ebSudheer Shanka
337ff866d286cf4df0948feeffa6e67848740e64ebSudheer Shanka/**
347ff866d286cf4df0948feeffa6e67848740e64ebSudheer Shanka * Helper class for managing settings preferences that can be disabled
357ff866d286cf4df0948feeffa6e67848740e64ebSudheer Shanka * by device admins via user restrictions.
367ff866d286cf4df0948feeffa6e67848740e64ebSudheer Shanka */
377ff866d286cf4df0948feeffa6e67848740e64ebSudheer Shankapublic class RestrictedPreferenceHelper {
387ff866d286cf4df0948feeffa6e67848740e64ebSudheer Shanka    private final Context mContext;
397ff866d286cf4df0948feeffa6e67848740e64ebSudheer Shanka    private final Preference mPreference;
407ff866d286cf4df0948feeffa6e67848740e64ebSudheer Shanka
417ff866d286cf4df0948feeffa6e67848740e64ebSudheer Shanka    private boolean mDisabledByAdmin;
427ff866d286cf4df0948feeffa6e67848740e64ebSudheer Shanka    private EnforcedAdmin mEnforcedAdmin;
437ff866d286cf4df0948feeffa6e67848740e64ebSudheer Shanka    private String mAttrUserRestriction = null;
44145017303494e77026bd99ec41476f6f53225d95Sudheer Shanka    private boolean mUseAdminDisabledSummary = false;
457ff866d286cf4df0948feeffa6e67848740e64ebSudheer Shanka
46ea088af5c12e25995a3992413c8f413abc22eeabSudheer Shanka    public RestrictedPreferenceHelper(Context context, Preference preference,
477ff866d286cf4df0948feeffa6e67848740e64ebSudheer Shanka            AttributeSet attrs) {
487ff866d286cf4df0948feeffa6e67848740e64ebSudheer Shanka        mContext = context;
497ff866d286cf4df0948feeffa6e67848740e64ebSudheer Shanka        mPreference = preference;
507ff866d286cf4df0948feeffa6e67848740e64ebSudheer Shanka
51ea088af5c12e25995a3992413c8f413abc22eeabSudheer Shanka        if (attrs != null) {
52ea088af5c12e25995a3992413c8f413abc22eeabSudheer Shanka            final TypedArray attributes = context.obtainStyledAttributes(attrs,
53ea088af5c12e25995a3992413c8f413abc22eeabSudheer Shanka                    R.styleable.RestrictedPreference);
54ea088af5c12e25995a3992413c8f413abc22eeabSudheer Shanka            final TypedValue userRestriction =
55ea088af5c12e25995a3992413c8f413abc22eeabSudheer Shanka                    attributes.peekValue(R.styleable.RestrictedPreference_userRestriction);
56ea088af5c12e25995a3992413c8f413abc22eeabSudheer Shanka            CharSequence data = null;
57ea088af5c12e25995a3992413c8f413abc22eeabSudheer Shanka            if (userRestriction != null && userRestriction.type == TypedValue.TYPE_STRING) {
58ea088af5c12e25995a3992413c8f413abc22eeabSudheer Shanka                if (userRestriction.resourceId != 0) {
59ea088af5c12e25995a3992413c8f413abc22eeabSudheer Shanka                    data = context.getText(userRestriction.resourceId);
60ea088af5c12e25995a3992413c8f413abc22eeabSudheer Shanka                } else {
61ea088af5c12e25995a3992413c8f413abc22eeabSudheer Shanka                    data = userRestriction.string;
62ea088af5c12e25995a3992413c8f413abc22eeabSudheer Shanka                }
637ff866d286cf4df0948feeffa6e67848740e64ebSudheer Shanka            }
64ea088af5c12e25995a3992413c8f413abc22eeabSudheer Shanka            mAttrUserRestriction = data == null ? null : data.toString();
65a8fbbb30eae03b9ed7a3e6ea78da13480a53b73dSudheer Shanka            // If the system has set the user restriction, then we shouldn't add the padlock.
66a8fbbb30eae03b9ed7a3e6ea78da13480a53b73dSudheer Shanka            if (RestrictedLockUtils.hasBaseUserRestriction(mContext, mAttrUserRestriction,
67a8fbbb30eae03b9ed7a3e6ea78da13480a53b73dSudheer Shanka                    UserHandle.myUserId())) {
68a8fbbb30eae03b9ed7a3e6ea78da13480a53b73dSudheer Shanka                mAttrUserRestriction = null;
69a8fbbb30eae03b9ed7a3e6ea78da13480a53b73dSudheer Shanka                return;
70a8fbbb30eae03b9ed7a3e6ea78da13480a53b73dSudheer Shanka            }
71145017303494e77026bd99ec41476f6f53225d95Sudheer Shanka
72145017303494e77026bd99ec41476f6f53225d95Sudheer Shanka            final TypedValue useAdminDisabledSummary =
73145017303494e77026bd99ec41476f6f53225d95Sudheer Shanka                    attributes.peekValue(R.styleable.RestrictedPreference_useAdminDisabledSummary);
74145017303494e77026bd99ec41476f6f53225d95Sudheer Shanka            if (useAdminDisabledSummary != null) {
75145017303494e77026bd99ec41476f6f53225d95Sudheer Shanka                mUseAdminDisabledSummary =
76145017303494e77026bd99ec41476f6f53225d95Sudheer Shanka                        (useAdminDisabledSummary.type == TypedValue.TYPE_INT_BOOLEAN
77145017303494e77026bd99ec41476f6f53225d95Sudheer Shanka                                && useAdminDisabledSummary.data != 0);
78145017303494e77026bd99ec41476f6f53225d95Sudheer Shanka            }
797ff866d286cf4df0948feeffa6e67848740e64ebSudheer Shanka        }
807ff866d286cf4df0948feeffa6e67848740e64ebSudheer Shanka    }
817ff866d286cf4df0948feeffa6e67848740e64ebSudheer Shanka
827ff866d286cf4df0948feeffa6e67848740e64ebSudheer Shanka    /**
837ff866d286cf4df0948feeffa6e67848740e64ebSudheer Shanka     * Modify PreferenceViewHolder to add padlock if restriction is disabled.
847ff866d286cf4df0948feeffa6e67848740e64ebSudheer Shanka     */
857ff866d286cf4df0948feeffa6e67848740e64ebSudheer Shanka    public void onBindViewHolder(PreferenceViewHolder holder) {
86923bc74c9227a684095cf95d808766f5dcd31bb5Sudheer Shanka        if (mDisabledByAdmin) {
87923bc74c9227a684095cf95d808766f5dcd31bb5Sudheer Shanka            holder.itemView.setEnabled(true);
887ff866d286cf4df0948feeffa6e67848740e64ebSudheer Shanka        }
89145017303494e77026bd99ec41476f6f53225d95Sudheer Shanka        if (mUseAdminDisabledSummary) {
90145017303494e77026bd99ec41476f6f53225d95Sudheer Shanka            final TextView summaryView = (TextView) holder.findViewById(android.R.id.summary);
91145017303494e77026bd99ec41476f6f53225d95Sudheer Shanka            if (summaryView != null) {
92fdfc88faef4d722b7ae09d8acd7a57a511b3eb72Fan Zhang                final CharSequence disabledText = summaryView.getContext().getText(
93fdfc88faef4d722b7ae09d8acd7a57a511b3eb72Fan Zhang                        R.string.disabled_by_admin_summary_text);
94145017303494e77026bd99ec41476f6f53225d95Sudheer Shanka                if (mDisabledByAdmin) {
95fdfc88faef4d722b7ae09d8acd7a57a511b3eb72Fan Zhang                    summaryView.setText(disabledText);
96fdfc88faef4d722b7ae09d8acd7a57a511b3eb72Fan Zhang                } else if (TextUtils.equals(disabledText, summaryView.getText())) {
97fdfc88faef4d722b7ae09d8acd7a57a511b3eb72Fan Zhang                    // It's previously set to disabled text, clear it.
98fdfc88faef4d722b7ae09d8acd7a57a511b3eb72Fan Zhang                    summaryView.setText(null);
99145017303494e77026bd99ec41476f6f53225d95Sudheer Shanka                }
100145017303494e77026bd99ec41476f6f53225d95Sudheer Shanka            }
101145017303494e77026bd99ec41476f6f53225d95Sudheer Shanka        }
102145017303494e77026bd99ec41476f6f53225d95Sudheer Shanka    }
103145017303494e77026bd99ec41476f6f53225d95Sudheer Shanka
104145017303494e77026bd99ec41476f6f53225d95Sudheer Shanka    public void useAdminDisabledSummary(boolean useSummary) {
105145017303494e77026bd99ec41476f6f53225d95Sudheer Shanka        mUseAdminDisabledSummary = useSummary;
1067ff866d286cf4df0948feeffa6e67848740e64ebSudheer Shanka    }
1077ff866d286cf4df0948feeffa6e67848740e64ebSudheer Shanka
1087ff866d286cf4df0948feeffa6e67848740e64ebSudheer Shanka    /**
1097ff866d286cf4df0948feeffa6e67848740e64ebSudheer Shanka     * Check if the preference is disabled if so handle the click by informing the user.
1107ff866d286cf4df0948feeffa6e67848740e64ebSudheer Shanka     *
1117ff866d286cf4df0948feeffa6e67848740e64ebSudheer Shanka     * @return true if the method handled the click.
1127ff866d286cf4df0948feeffa6e67848740e64ebSudheer Shanka     */
1137ff866d286cf4df0948feeffa6e67848740e64ebSudheer Shanka    public boolean performClick() {
1147ff866d286cf4df0948feeffa6e67848740e64ebSudheer Shanka        if (mDisabledByAdmin) {
1157ff866d286cf4df0948feeffa6e67848740e64ebSudheer Shanka            RestrictedLockUtils.sendShowAdminSupportDetailsIntent(mContext, mEnforcedAdmin);
1167ff866d286cf4df0948feeffa6e67848740e64ebSudheer Shanka            return true;
1177ff866d286cf4df0948feeffa6e67848740e64ebSudheer Shanka        }
1187ff866d286cf4df0948feeffa6e67848740e64ebSudheer Shanka        return false;
1197ff866d286cf4df0948feeffa6e67848740e64ebSudheer Shanka    }
1207ff866d286cf4df0948feeffa6e67848740e64ebSudheer Shanka
1217ff866d286cf4df0948feeffa6e67848740e64ebSudheer Shanka    /**
1227ff866d286cf4df0948feeffa6e67848740e64ebSudheer Shanka     * Disable / enable if we have been passed the restriction in the xml.
1237ff866d286cf4df0948feeffa6e67848740e64ebSudheer Shanka     */
124ea088af5c12e25995a3992413c8f413abc22eeabSudheer Shanka    public void onAttachedToHierarchy() {
1257ff866d286cf4df0948feeffa6e67848740e64ebSudheer Shanka        if (mAttrUserRestriction != null) {
1267ff866d286cf4df0948feeffa6e67848740e64ebSudheer Shanka            checkRestrictionAndSetDisabled(mAttrUserRestriction, UserHandle.myUserId());
1277ff866d286cf4df0948feeffa6e67848740e64ebSudheer Shanka        }
1287ff866d286cf4df0948feeffa6e67848740e64ebSudheer Shanka    }
1297ff866d286cf4df0948feeffa6e67848740e64ebSudheer Shanka
1307ff866d286cf4df0948feeffa6e67848740e64ebSudheer Shanka    /**
1317ff866d286cf4df0948feeffa6e67848740e64ebSudheer Shanka     * Set the user restriction that is used to disable this preference.
1327ff866d286cf4df0948feeffa6e67848740e64ebSudheer Shanka     *
1337ff866d286cf4df0948feeffa6e67848740e64ebSudheer Shanka     * @param userRestriction constant from {@link android.os.UserManager}
1347ff866d286cf4df0948feeffa6e67848740e64ebSudheer Shanka     * @param userId user to check the restriction for.
1357ff866d286cf4df0948feeffa6e67848740e64ebSudheer Shanka     */
1367ff866d286cf4df0948feeffa6e67848740e64ebSudheer Shanka    public void checkRestrictionAndSetDisabled(String userRestriction, int userId) {
1377ff866d286cf4df0948feeffa6e67848740e64ebSudheer Shanka        EnforcedAdmin admin = RestrictedLockUtils.checkIfRestrictionEnforced(mContext,
1387ff866d286cf4df0948feeffa6e67848740e64ebSudheer Shanka                userRestriction, userId);
1397ff866d286cf4df0948feeffa6e67848740e64ebSudheer Shanka        setDisabledByAdmin(admin);
1407ff866d286cf4df0948feeffa6e67848740e64ebSudheer Shanka    }
1417ff866d286cf4df0948feeffa6e67848740e64ebSudheer Shanka
1427ff866d286cf4df0948feeffa6e67848740e64ebSudheer Shanka    /**
1437ff866d286cf4df0948feeffa6e67848740e64ebSudheer Shanka     * Disable this preference based on the enforce admin.
1447ff866d286cf4df0948feeffa6e67848740e64ebSudheer Shanka     *
1457ff866d286cf4df0948feeffa6e67848740e64ebSudheer Shanka     * @param EnforcedAdmin Details of the admin who enforced the restriction. If it
1467ff866d286cf4df0948feeffa6e67848740e64ebSudheer Shanka     * is {@code null}, then this preference will be enabled. Otherwise, it will be disabled.
1477ff866d286cf4df0948feeffa6e67848740e64ebSudheer Shanka     * @return true if the disabled state was changed.
1487ff866d286cf4df0948feeffa6e67848740e64ebSudheer Shanka     */
1497ff866d286cf4df0948feeffa6e67848740e64ebSudheer Shanka    public boolean setDisabledByAdmin(EnforcedAdmin admin) {
1507ff866d286cf4df0948feeffa6e67848740e64ebSudheer Shanka        final boolean disabled = (admin != null ? true : false);
1518d774b752b4f8f9ff64c23b02ec923508fe25068Sudheer Shanka        mEnforcedAdmin = admin;
1522893302afc4137e63c9174a5d471d1f18b8b5d87Sudheer Shanka        boolean changed = false;
1537ff866d286cf4df0948feeffa6e67848740e64ebSudheer Shanka        if (mDisabledByAdmin != disabled) {
1547ff866d286cf4df0948feeffa6e67848740e64ebSudheer Shanka            mDisabledByAdmin = disabled;
1552893302afc4137e63c9174a5d471d1f18b8b5d87Sudheer Shanka            changed = true;
1567ff866d286cf4df0948feeffa6e67848740e64ebSudheer Shanka        }
1572893302afc4137e63c9174a5d471d1f18b8b5d87Sudheer Shanka        mPreference.setEnabled(!disabled);
1582893302afc4137e63c9174a5d471d1f18b8b5d87Sudheer Shanka        return changed;
1597ff866d286cf4df0948feeffa6e67848740e64ebSudheer Shanka    }
1607ff866d286cf4df0948feeffa6e67848740e64ebSudheer Shanka
1617ff866d286cf4df0948feeffa6e67848740e64ebSudheer Shanka    public boolean isDisabledByAdmin() {
1627ff866d286cf4df0948feeffa6e67848740e64ebSudheer Shanka        return mDisabledByAdmin;
1637ff866d286cf4df0948feeffa6e67848740e64ebSudheer Shanka    }
1647ff866d286cf4df0948feeffa6e67848740e64ebSudheer Shanka}
165