1/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License
15 */
16
17package com.android.settingslib;
18
19import android.content.Context;
20import android.content.res.TypedArray;
21import android.graphics.drawable.Drawable;
22import android.os.UserHandle;
23import android.support.v7.preference.Preference;
24import android.support.v7.preference.PreferenceViewHolder;
25import android.util.AttributeSet;
26import android.util.TypedValue;
27import android.view.View;
28import android.widget.TextView;
29
30import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
31
32/**
33 * Helper class for managing settings preferences that can be disabled
34 * by device admins via user restrictions.
35 */
36public class RestrictedPreferenceHelper {
37    private final Context mContext;
38    private final Preference mPreference;
39
40    private boolean mDisabledByAdmin;
41    private EnforcedAdmin mEnforcedAdmin;
42    private String mAttrUserRestriction = null;
43    private boolean mUseAdminDisabledSummary = false;
44
45    public RestrictedPreferenceHelper(Context context, Preference preference,
46            AttributeSet attrs) {
47        mContext = context;
48        mPreference = preference;
49
50        if (attrs != null) {
51            final TypedArray attributes = context.obtainStyledAttributes(attrs,
52                    R.styleable.RestrictedPreference);
53            final TypedValue userRestriction =
54                    attributes.peekValue(R.styleable.RestrictedPreference_userRestriction);
55            CharSequence data = null;
56            if (userRestriction != null && userRestriction.type == TypedValue.TYPE_STRING) {
57                if (userRestriction.resourceId != 0) {
58                    data = context.getText(userRestriction.resourceId);
59                } else {
60                    data = userRestriction.string;
61                }
62            }
63            mAttrUserRestriction = data == null ? null : data.toString();
64            // If the system has set the user restriction, then we shouldn't add the padlock.
65            if (RestrictedLockUtils.hasBaseUserRestriction(mContext, mAttrUserRestriction,
66                    UserHandle.myUserId())) {
67                mAttrUserRestriction = null;
68                return;
69            }
70
71            final TypedValue useAdminDisabledSummary =
72                    attributes.peekValue(R.styleable.RestrictedPreference_useAdminDisabledSummary);
73            if (useAdminDisabledSummary != null) {
74                mUseAdminDisabledSummary =
75                        (useAdminDisabledSummary.type == TypedValue.TYPE_INT_BOOLEAN
76                                && useAdminDisabledSummary.data != 0);
77            }
78        }
79    }
80
81    /**
82     * Modify PreferenceViewHolder to add padlock if restriction is disabled.
83     */
84    public void onBindViewHolder(PreferenceViewHolder holder) {
85        if (mDisabledByAdmin) {
86            holder.itemView.setEnabled(true);
87        }
88        if (mUseAdminDisabledSummary) {
89            final TextView summaryView = (TextView) holder.findViewById(android.R.id.summary);
90            if (summaryView != null) {
91                if (mDisabledByAdmin) {
92                    summaryView.setText(R.string.disabled_by_admin_summary_text);
93                    summaryView.setVisibility(View.VISIBLE);
94                } else {
95                    summaryView.setVisibility(View.GONE);
96                }
97            }
98        }
99    }
100
101    public void useAdminDisabledSummary(boolean useSummary) {
102        mUseAdminDisabledSummary = useSummary;
103    }
104
105    /**
106     * Check if the preference is disabled if so handle the click by informing the user.
107     *
108     * @return true if the method handled the click.
109     */
110    public boolean performClick() {
111        if (mDisabledByAdmin) {
112            RestrictedLockUtils.sendShowAdminSupportDetailsIntent(mContext, mEnforcedAdmin);
113            return true;
114        }
115        return false;
116    }
117
118    /**
119     * Disable / enable if we have been passed the restriction in the xml.
120     */
121    public void onAttachedToHierarchy() {
122        if (mAttrUserRestriction != null) {
123            checkRestrictionAndSetDisabled(mAttrUserRestriction, UserHandle.myUserId());
124        }
125    }
126
127    /**
128     * Set the user restriction that is used to disable this preference.
129     *
130     * @param userRestriction constant from {@link android.os.UserManager}
131     * @param userId user to check the restriction for.
132     */
133    public void checkRestrictionAndSetDisabled(String userRestriction, int userId) {
134        EnforcedAdmin admin = RestrictedLockUtils.checkIfRestrictionEnforced(mContext,
135                userRestriction, userId);
136        setDisabledByAdmin(admin);
137    }
138
139    /**
140     * Disable this preference based on the enforce admin.
141     *
142     * @param EnforcedAdmin Details of the admin who enforced the restriction. If it
143     * is {@code null}, then this preference will be enabled. Otherwise, it will be disabled.
144     * @return true if the disabled state was changed.
145     */
146    public boolean setDisabledByAdmin(EnforcedAdmin admin) {
147        final boolean disabled = (admin != null ? true : false);
148        mEnforcedAdmin = admin;
149        boolean changed = false;
150        if (mDisabledByAdmin != disabled) {
151            mDisabledByAdmin = disabled;
152            changed = true;
153        }
154        mPreference.setEnabled(!disabled);
155        return changed;
156    }
157
158    public boolean isDisabledByAdmin() {
159        return mDisabledByAdmin;
160    }
161}
162