141937766981423c9252e12e3319b2e7532739627Fabrice Di Meglio/*
241937766981423c9252e12e3319b2e7532739627Fabrice Di Meglio * Copyright (C) 2014 The Android Open Source Project
341937766981423c9252e12e3319b2e7532739627Fabrice Di Meglio *
441937766981423c9252e12e3319b2e7532739627Fabrice Di Meglio * Licensed under the Apache License, Version 2.0 (the "License");
541937766981423c9252e12e3319b2e7532739627Fabrice Di Meglio * you may not use this file except in compliance with the License.
641937766981423c9252e12e3319b2e7532739627Fabrice Di Meglio * You may obtain a copy of the License at
741937766981423c9252e12e3319b2e7532739627Fabrice Di Meglio *
841937766981423c9252e12e3319b2e7532739627Fabrice Di Meglio *      http://www.apache.org/licenses/LICENSE-2.0
941937766981423c9252e12e3319b2e7532739627Fabrice Di Meglio *
1041937766981423c9252e12e3319b2e7532739627Fabrice Di Meglio * Unless required by applicable law or agreed to in writing, software
1141937766981423c9252e12e3319b2e7532739627Fabrice Di Meglio * distributed under the License is distributed on an "AS IS" BASIS,
1241937766981423c9252e12e3319b2e7532739627Fabrice Di Meglio * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1341937766981423c9252e12e3319b2e7532739627Fabrice Di Meglio * See the License for the specific language governing permissions and
1441937766981423c9252e12e3319b2e7532739627Fabrice Di Meglio * limitations under the License.
1541937766981423c9252e12e3319b2e7532739627Fabrice Di Meglio */
1641937766981423c9252e12e3319b2e7532739627Fabrice Di Meglio
1741937766981423c9252e12e3319b2e7532739627Fabrice Di Megliopackage com.android.settings.widget;
1841937766981423c9252e12e3319b2e7532739627Fabrice Di Meglio
1941937766981423c9252e12e3319b2e7532739627Fabrice Di Meglioimport android.content.Context;
201b18665dbc49663f290859ce9cdf3237b8a30b7cFabrice Di Meglioimport android.content.res.TypedArray;
21138ff8c0457c6e1345015973668d652fa17c7c3bFabrice Di Meglioimport android.os.Parcel;
22138ff8c0457c6e1345015973668d652fa17c7c3bFabrice Di Meglioimport android.os.Parcelable;
23b47b2c3f6af650441f8069b87d0d82549913f7c5John Spurlockimport android.text.SpannableStringBuilder;
24b47b2c3f6af650441f8069b87d0d82549913f7c5John Spurlockimport android.text.TextUtils;
25b47b2c3f6af650441f8069b87d0d82549913f7c5John Spurlockimport android.text.style.TextAppearanceSpan;
2641937766981423c9252e12e3319b2e7532739627Fabrice Di Meglioimport android.util.AttributeSet;
2741937766981423c9252e12e3319b2e7532739627Fabrice Di Meglioimport android.view.LayoutInflater;
2841937766981423c9252e12e3319b2e7532739627Fabrice Di Meglioimport android.view.View;
291b18665dbc49663f290859ce9cdf3237b8a30b7cFabrice Di Meglioimport android.view.ViewGroup;
30c99d0a8a797aba4ec75ffdc766a3ca131ab84103Maxim Bogatovimport android.view.accessibility.AccessibilityEvent;
31c99d0a8a797aba4ec75ffdc766a3ca131ab84103Maxim Bogatovimport android.view.accessibility.AccessibilityNodeInfo;
3241937766981423c9252e12e3319b2e7532739627Fabrice Di Meglioimport android.widget.CompoundButton;
3341937766981423c9252e12e3319b2e7532739627Fabrice Di Meglioimport android.widget.LinearLayout;
3441937766981423c9252e12e3319b2e7532739627Fabrice Di Meglioimport android.widget.Switch;
3541937766981423c9252e12e3319b2e7532739627Fabrice Di Meglioimport android.widget.TextView;
36b47b2c3f6af650441f8069b87d0d82549913f7c5John Spurlock
3741937766981423c9252e12e3319b2e7532739627Fabrice Di Meglioimport com.android.settings.R;
38aa71afe5978b1340a2d702f3a75d22baf8c96348Fan Zhangimport com.android.settings.core.instrumentation.MetricsFeatureProvider;
39aa71afe5978b1340a2d702f3a75d22baf8c96348Fan Zhangimport com.android.settings.overlay.FeatureFactory;
409c32468cd59cbe5b8e7692235a67034c936b4788Sudheer Shankaimport com.android.settingslib.RestrictedLockUtils;
419c32468cd59cbe5b8e7692235a67034c936b4788Sudheer Shanka
4241937766981423c9252e12e3319b2e7532739627Fabrice Di Meglioimport java.util.ArrayList;
4341937766981423c9252e12e3319b2e7532739627Fabrice Di Meglio
44aa71afe5978b1340a2d702f3a75d22baf8c96348Fan Zhangimport static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
45aa71afe5978b1340a2d702f3a75d22baf8c96348Fan Zhang
46e9cb75c636234e44c94b38a877f3c60091d907dcFabrice Di Megliopublic class SwitchBar extends LinearLayout implements CompoundButton.OnCheckedChangeListener,
47e9cb75c636234e44c94b38a877f3c60091d907dcFabrice Di Meglio        View.OnClickListener {
4841937766981423c9252e12e3319b2e7532739627Fabrice Di Meglio
496d2a0c80df01a95adccfbb5926b1c463b60f6366Fan Zhang    public interface OnSwitchChangeListener {
5041937766981423c9252e12e3319b2e7532739627Fabrice Di Meglio        /**
5141937766981423c9252e12e3319b2e7532739627Fabrice Di Meglio         * Called when the checked state of the Switch has changed.
5241937766981423c9252e12e3319b2e7532739627Fabrice Di Meglio         *
5341937766981423c9252e12e3319b2e7532739627Fabrice Di Meglio         * @param switchView The Switch view whose state has changed.
5441937766981423c9252e12e3319b2e7532739627Fabrice Di Meglio         * @param isChecked  The new checked state of switchView.
5541937766981423c9252e12e3319b2e7532739627Fabrice Di Meglio         */
5641937766981423c9252e12e3319b2e7532739627Fabrice Di Meglio        void onSwitchChanged(Switch switchView, boolean isChecked);
5741937766981423c9252e12e3319b2e7532739627Fabrice Di Meglio    }
5841937766981423c9252e12e3319b2e7532739627Fabrice Di Meglio
59aa71afe5978b1340a2d702f3a75d22baf8c96348Fan Zhang    private MetricsFeatureProvider mMetricsFeatureProvider;
60b47b2c3f6af650441f8069b87d0d82549913f7c5John Spurlock    private final TextAppearanceSpan mSummarySpan;
61b47b2c3f6af650441f8069b87d0d82549913f7c5John Spurlock
621b18665dbc49663f290859ce9cdf3237b8a30b7cFabrice Di Meglio    private ToggleSwitch mSwitch;
63115d15763d95c2f93a639ad2569037d274d46a22Sudheer Shanka    private View mRestrictedIcon;
641b18665dbc49663f290859ce9cdf3237b8a30b7cFabrice Di Meglio    private TextView mTextView;
65b47b2c3f6af650441f8069b87d0d82549913f7c5John Spurlock    private String mLabel;
66b47b2c3f6af650441f8069b87d0d82549913f7c5John Spurlock    private String mSummary;
671b18665dbc49663f290859ce9cdf3237b8a30b7cFabrice Di Meglio
686d2a0c80df01a95adccfbb5926b1c463b60f6366Fan Zhang    private boolean mLoggingIntialized;
696d2a0c80df01a95adccfbb5926b1c463b60f6366Fan Zhang    private boolean mDisabledByAdmin;
709c32468cd59cbe5b8e7692235a67034c936b4788Sudheer Shanka    private EnforcedAdmin mEnforcedAdmin = null;
719c32468cd59cbe5b8e7692235a67034c936b4788Sudheer Shanka
72e4ebcd12be7baae58a1fabcda6c7544c911c95ebJason Monk    private String mMetricsTag;
73e4ebcd12be7baae58a1fabcda6c7544c911c95ebJason Monk
741b18665dbc49663f290859ce9cdf3237b8a30b7cFabrice Di Meglio    private ArrayList<OnSwitchChangeListener> mSwitchChangeListeners =
751b18665dbc49663f290859ce9cdf3237b8a30b7cFabrice Di Meglio            new ArrayList<OnSwitchChangeListener>();
761b18665dbc49663f290859ce9cdf3237b8a30b7cFabrice Di Meglio
770285c806647ad7e84302044587b56e9d1c918b85Anna Galusza    private static int[] XML_ATTRIBUTES = {
780285c806647ad7e84302044587b56e9d1c918b85Anna Galusza            R.attr.switchBarMarginStart, R.attr.switchBarMarginEnd,
790285c806647ad7e84302044587b56e9d1c918b85Anna Galusza            R.attr.switchBarBackgroundColor};
801b18665dbc49663f290859ce9cdf3237b8a30b7cFabrice Di Meglio
8141937766981423c9252e12e3319b2e7532739627Fabrice Di Meglio    public SwitchBar(Context context) {
8241937766981423c9252e12e3319b2e7532739627Fabrice Di Meglio        this(context, null);
8341937766981423c9252e12e3319b2e7532739627Fabrice Di Meglio    }
8441937766981423c9252e12e3319b2e7532739627Fabrice Di Meglio
8541937766981423c9252e12e3319b2e7532739627Fabrice Di Meglio    public SwitchBar(Context context, AttributeSet attrs) {
8641937766981423c9252e12e3319b2e7532739627Fabrice Di Meglio        this(context, attrs, 0);
8741937766981423c9252e12e3319b2e7532739627Fabrice Di Meglio    }
8841937766981423c9252e12e3319b2e7532739627Fabrice Di Meglio
8941937766981423c9252e12e3319b2e7532739627Fabrice Di Meglio    public SwitchBar(Context context, AttributeSet attrs, int defStyleAttr) {
9041937766981423c9252e12e3319b2e7532739627Fabrice Di Meglio        this(context, attrs, defStyleAttr, 0);
9141937766981423c9252e12e3319b2e7532739627Fabrice Di Meglio    }
9241937766981423c9252e12e3319b2e7532739627Fabrice Di Meglio
9341937766981423c9252e12e3319b2e7532739627Fabrice Di Meglio    public SwitchBar(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
9441937766981423c9252e12e3319b2e7532739627Fabrice Di Meglio        super(context, attrs, defStyleAttr, defStyleRes);
9541937766981423c9252e12e3319b2e7532739627Fabrice Di Meglio
9641937766981423c9252e12e3319b2e7532739627Fabrice Di Meglio        LayoutInflater.from(context).inflate(R.layout.switch_bar, this);
9741937766981423c9252e12e3319b2e7532739627Fabrice Di Meglio
980285c806647ad7e84302044587b56e9d1c918b85Anna Galusza        final TypedArray a = context.obtainStyledAttributes(attrs, XML_ATTRIBUTES);
991b18665dbc49663f290859ce9cdf3237b8a30b7cFabrice Di Meglio        int switchBarMarginStart = (int) a.getDimension(0, 0);
1001b18665dbc49663f290859ce9cdf3237b8a30b7cFabrice Di Meglio        int switchBarMarginEnd = (int) a.getDimension(1, 0);
1010285c806647ad7e84302044587b56e9d1c918b85Anna Galusza        int switchBarBackgroundColor = (int) a.getColor(2, 0);
1021b18665dbc49663f290859ce9cdf3237b8a30b7cFabrice Di Meglio        a.recycle();
1031b18665dbc49663f290859ce9cdf3237b8a30b7cFabrice Di Meglio
10441937766981423c9252e12e3319b2e7532739627Fabrice Di Meglio        mTextView = (TextView) findViewById(R.id.switch_text);
105c99d0a8a797aba4ec75ffdc766a3ca131ab84103Maxim Bogatov        mTextView.setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_NO);
106b47b2c3f6af650441f8069b87d0d82549913f7c5John Spurlock        mLabel = getResources().getString(R.string.switch_off_text);
107b47b2c3f6af650441f8069b87d0d82549913f7c5John Spurlock        mSummarySpan = new TextAppearanceSpan(mContext, R.style.TextAppearance_Small_SwitchBar);
108b47b2c3f6af650441f8069b87d0d82549913f7c5John Spurlock        updateText();
1091b18665dbc49663f290859ce9cdf3237b8a30b7cFabrice Di Meglio        ViewGroup.MarginLayoutParams lp = (MarginLayoutParams) mTextView.getLayoutParams();
1101b18665dbc49663f290859ce9cdf3237b8a30b7cFabrice Di Meglio        lp.setMarginStart(switchBarMarginStart);
11141937766981423c9252e12e3319b2e7532739627Fabrice Di Meglio
1126220275d6dec8ffc6f1df2cbfbf42934d09d41f0Fabrice Di Meglio        mSwitch = (ToggleSwitch) findViewById(R.id.switch_widget);
113d2b1e441b7314640b2c51ca367c6cc3925147a81Fabrice Di Meglio        // Prevent onSaveInstanceState() to be called as we are managing the state of the Switch
114d2b1e441b7314640b2c51ca367c6cc3925147a81Fabrice Di Meglio        // on our own
115d2b1e441b7314640b2c51ca367c6cc3925147a81Fabrice Di Meglio        mSwitch.setSaveEnabled(false);
116c99d0a8a797aba4ec75ffdc766a3ca131ab84103Maxim Bogatov        mSwitch.setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_NO);
1171b18665dbc49663f290859ce9cdf3237b8a30b7cFabrice Di Meglio        lp = (MarginLayoutParams) mSwitch.getLayoutParams();
1181b18665dbc49663f290859ce9cdf3237b8a30b7cFabrice Di Meglio        lp.setMarginEnd(switchBarMarginEnd);
1190285c806647ad7e84302044587b56e9d1c918b85Anna Galusza        setBackgroundColor(switchBarBackgroundColor);
12041937766981423c9252e12e3319b2e7532739627Fabrice Di Meglio
12141937766981423c9252e12e3319b2e7532739627Fabrice Di Meglio        addOnSwitchChangeListener(new OnSwitchChangeListener() {
12241937766981423c9252e12e3319b2e7532739627Fabrice Di Meglio            @Override
12341937766981423c9252e12e3319b2e7532739627Fabrice Di Meglio            public void onSwitchChanged(Switch switchView, boolean isChecked) {
124138ff8c0457c6e1345015973668d652fa17c7c3bFabrice Di Meglio                setTextViewLabel(isChecked);
12541937766981423c9252e12e3319b2e7532739627Fabrice Di Meglio            }
12641937766981423c9252e12e3319b2e7532739627Fabrice Di Meglio        });
12741937766981423c9252e12e3319b2e7532739627Fabrice Di Meglio
128115d15763d95c2f93a639ad2569037d274d46a22Sudheer Shanka        mRestrictedIcon = findViewById(R.id.restricted_icon);
129115d15763d95c2f93a639ad2569037d274d46a22Sudheer Shanka
130e9cb75c636234e44c94b38a877f3c60091d907dcFabrice Di Meglio        setOnClickListener(this);
131e9cb75c636234e44c94b38a877f3c60091d907dcFabrice Di Meglio
13241937766981423c9252e12e3319b2e7532739627Fabrice Di Meglio        // Default is hide
13341937766981423c9252e12e3319b2e7532739627Fabrice Di Meglio        setVisibility(View.GONE);
134aa71afe5978b1340a2d702f3a75d22baf8c96348Fan Zhang
135aa71afe5978b1340a2d702f3a75d22baf8c96348Fan Zhang        mMetricsFeatureProvider = FeatureFactory.getFactory(context).getMetricsFeatureProvider();
13641937766981423c9252e12e3319b2e7532739627Fabrice Di Meglio    }
13741937766981423c9252e12e3319b2e7532739627Fabrice Di Meglio
138e4ebcd12be7baae58a1fabcda6c7544c911c95ebJason Monk    public void setMetricsTag(String tag) {
139e4ebcd12be7baae58a1fabcda6c7544c911c95ebJason Monk        mMetricsTag = tag;
140e4ebcd12be7baae58a1fabcda6c7544c911c95ebJason Monk    }
141e4ebcd12be7baae58a1fabcda6c7544c911c95ebJason Monk
142138ff8c0457c6e1345015973668d652fa17c7c3bFabrice Di Meglio    public void setTextViewLabel(boolean isChecked) {
143b47b2c3f6af650441f8069b87d0d82549913f7c5John Spurlock        mLabel = getResources()
144b47b2c3f6af650441f8069b87d0d82549913f7c5John Spurlock                .getString(isChecked ? R.string.switch_on_text : R.string.switch_off_text);
145b47b2c3f6af650441f8069b87d0d82549913f7c5John Spurlock        updateText();
146b47b2c3f6af650441f8069b87d0d82549913f7c5John Spurlock    }
147b47b2c3f6af650441f8069b87d0d82549913f7c5John Spurlock
148b47b2c3f6af650441f8069b87d0d82549913f7c5John Spurlock    public void setSummary(String summary) {
149b47b2c3f6af650441f8069b87d0d82549913f7c5John Spurlock        mSummary = summary;
150b47b2c3f6af650441f8069b87d0d82549913f7c5John Spurlock        updateText();
151b47b2c3f6af650441f8069b87d0d82549913f7c5John Spurlock    }
152b47b2c3f6af650441f8069b87d0d82549913f7c5John Spurlock
153b47b2c3f6af650441f8069b87d0d82549913f7c5John Spurlock    private void updateText() {
154b47b2c3f6af650441f8069b87d0d82549913f7c5John Spurlock        if (TextUtils.isEmpty(mSummary)) {
155b47b2c3f6af650441f8069b87d0d82549913f7c5John Spurlock            mTextView.setText(mLabel);
156b47b2c3f6af650441f8069b87d0d82549913f7c5John Spurlock            return;
157b47b2c3f6af650441f8069b87d0d82549913f7c5John Spurlock        }
158b47b2c3f6af650441f8069b87d0d82549913f7c5John Spurlock        final SpannableStringBuilder ssb = new SpannableStringBuilder(mLabel).append('\n');
159b47b2c3f6af650441f8069b87d0d82549913f7c5John Spurlock        final int start = ssb.length();
160b47b2c3f6af650441f8069b87d0d82549913f7c5John Spurlock        ssb.append(mSummary);
161b47b2c3f6af650441f8069b87d0d82549913f7c5John Spurlock        ssb.setSpan(mSummarySpan, start, ssb.length(), 0);
162b47b2c3f6af650441f8069b87d0d82549913f7c5John Spurlock        mTextView.setText(ssb);
163138ff8c0457c6e1345015973668d652fa17c7c3bFabrice Di Meglio    }
164138ff8c0457c6e1345015973668d652fa17c7c3bFabrice Di Meglio
165138ff8c0457c6e1345015973668d652fa17c7c3bFabrice Di Meglio    public void setChecked(boolean checked) {
166138ff8c0457c6e1345015973668d652fa17c7c3bFabrice Di Meglio        setTextViewLabel(checked);
167138ff8c0457c6e1345015973668d652fa17c7c3bFabrice Di Meglio        mSwitch.setChecked(checked);
168138ff8c0457c6e1345015973668d652fa17c7c3bFabrice Di Meglio    }
169138ff8c0457c6e1345015973668d652fa17c7c3bFabrice Di Meglio
170006b2cca1311e61472a8b66fb0c50854fc36d2e7Fabrice Di Meglio    public void setCheckedInternal(boolean checked) {
171006b2cca1311e61472a8b66fb0c50854fc36d2e7Fabrice Di Meglio        setTextViewLabel(checked);
172006b2cca1311e61472a8b66fb0c50854fc36d2e7Fabrice Di Meglio        mSwitch.setCheckedInternal(checked);
173006b2cca1311e61472a8b66fb0c50854fc36d2e7Fabrice Di Meglio    }
174006b2cca1311e61472a8b66fb0c50854fc36d2e7Fabrice Di Meglio
175138ff8c0457c6e1345015973668d652fa17c7c3bFabrice Di Meglio    public boolean isChecked() {
176138ff8c0457c6e1345015973668d652fa17c7c3bFabrice Di Meglio        return mSwitch.isChecked();
177138ff8c0457c6e1345015973668d652fa17c7c3bFabrice Di Meglio    }
178138ff8c0457c6e1345015973668d652fa17c7c3bFabrice Di Meglio
179138ff8c0457c6e1345015973668d652fa17c7c3bFabrice Di Meglio    public void setEnabled(boolean enabled) {
1809c32468cd59cbe5b8e7692235a67034c936b4788Sudheer Shanka        if (enabled && mDisabledByAdmin) {
1819c32468cd59cbe5b8e7692235a67034c936b4788Sudheer Shanka            setDisabledByAdmin(null);
1829c32468cd59cbe5b8e7692235a67034c936b4788Sudheer Shanka            return;
1839c32468cd59cbe5b8e7692235a67034c936b4788Sudheer Shanka        }
184138ff8c0457c6e1345015973668d652fa17c7c3bFabrice Di Meglio        super.setEnabled(enabled);
185138ff8c0457c6e1345015973668d652fa17c7c3bFabrice Di Meglio        mTextView.setEnabled(enabled);
186b18e2423667b132d8de428fdbdb32572a1befe62Lifu Tang        mSwitch.setEnabled(enabled);
187138ff8c0457c6e1345015973668d652fa17c7c3bFabrice Di Meglio    }
188138ff8c0457c6e1345015973668d652fa17c7c3bFabrice Di Meglio
1899c32468cd59cbe5b8e7692235a67034c936b4788Sudheer Shanka    /**
1909c32468cd59cbe5b8e7692235a67034c936b4788Sudheer Shanka     * If admin is not null, disables the text and switch but keeps the view clickable.
1919c32468cd59cbe5b8e7692235a67034c936b4788Sudheer Shanka     * Otherwise, calls setEnabled which will enables the entire view including
1929c32468cd59cbe5b8e7692235a67034c936b4788Sudheer Shanka     * the text and switch.
1939c32468cd59cbe5b8e7692235a67034c936b4788Sudheer Shanka     */
1949c32468cd59cbe5b8e7692235a67034c936b4788Sudheer Shanka    public void setDisabledByAdmin(EnforcedAdmin admin) {
1959c32468cd59cbe5b8e7692235a67034c936b4788Sudheer Shanka        mEnforcedAdmin = admin;
1969c32468cd59cbe5b8e7692235a67034c936b4788Sudheer Shanka        if (admin != null) {
1979c32468cd59cbe5b8e7692235a67034c936b4788Sudheer Shanka            super.setEnabled(true);
1989c32468cd59cbe5b8e7692235a67034c936b4788Sudheer Shanka            mDisabledByAdmin = true;
1999c32468cd59cbe5b8e7692235a67034c936b4788Sudheer Shanka            mTextView.setEnabled(false);
2009c32468cd59cbe5b8e7692235a67034c936b4788Sudheer Shanka            mSwitch.setEnabled(false);
201115d15763d95c2f93a639ad2569037d274d46a22Sudheer Shanka            mSwitch.setVisibility(View.GONE);
202115d15763d95c2f93a639ad2569037d274d46a22Sudheer Shanka            mRestrictedIcon.setVisibility(View.VISIBLE);
2039c32468cd59cbe5b8e7692235a67034c936b4788Sudheer Shanka        } else {
2049c32468cd59cbe5b8e7692235a67034c936b4788Sudheer Shanka            mDisabledByAdmin = false;
205115d15763d95c2f93a639ad2569037d274d46a22Sudheer Shanka            mSwitch.setVisibility(View.VISIBLE);
206115d15763d95c2f93a639ad2569037d274d46a22Sudheer Shanka            mRestrictedIcon.setVisibility(View.GONE);
2079c32468cd59cbe5b8e7692235a67034c936b4788Sudheer Shanka            setEnabled(true);
2089c32468cd59cbe5b8e7692235a67034c936b4788Sudheer Shanka        }
2099c32468cd59cbe5b8e7692235a67034c936b4788Sudheer Shanka    }
2109c32468cd59cbe5b8e7692235a67034c936b4788Sudheer Shanka
211138ff8c0457c6e1345015973668d652fa17c7c3bFabrice Di Meglio    public final ToggleSwitch getSwitch() {
21241937766981423c9252e12e3319b2e7532739627Fabrice Di Meglio        return mSwitch;
21341937766981423c9252e12e3319b2e7532739627Fabrice Di Meglio    }
21441937766981423c9252e12e3319b2e7532739627Fabrice Di Meglio
21541937766981423c9252e12e3319b2e7532739627Fabrice Di Meglio    public void show() {
216138ff8c0457c6e1345015973668d652fa17c7c3bFabrice Di Meglio        if (!isShowing()) {
217138ff8c0457c6e1345015973668d652fa17c7c3bFabrice Di Meglio            setVisibility(View.VISIBLE);
218138ff8c0457c6e1345015973668d652fa17c7c3bFabrice Di Meglio            mSwitch.setOnCheckedChangeListener(this);
219138ff8c0457c6e1345015973668d652fa17c7c3bFabrice Di Meglio        }
22041937766981423c9252e12e3319b2e7532739627Fabrice Di Meglio    }
22141937766981423c9252e12e3319b2e7532739627Fabrice Di Meglio
22241937766981423c9252e12e3319b2e7532739627Fabrice Di Meglio    public void hide() {
223138ff8c0457c6e1345015973668d652fa17c7c3bFabrice Di Meglio        if (isShowing()) {
224138ff8c0457c6e1345015973668d652fa17c7c3bFabrice Di Meglio            setVisibility(View.GONE);
225138ff8c0457c6e1345015973668d652fa17c7c3bFabrice Di Meglio            mSwitch.setOnCheckedChangeListener(null);
226138ff8c0457c6e1345015973668d652fa17c7c3bFabrice Di Meglio        }
22741937766981423c9252e12e3319b2e7532739627Fabrice Di Meglio    }
22841937766981423c9252e12e3319b2e7532739627Fabrice Di Meglio
22941937766981423c9252e12e3319b2e7532739627Fabrice Di Meglio    public boolean isShowing() {
23041937766981423c9252e12e3319b2e7532739627Fabrice Di Meglio        return (getVisibility() == View.VISIBLE);
23141937766981423c9252e12e3319b2e7532739627Fabrice Di Meglio    }
23241937766981423c9252e12e3319b2e7532739627Fabrice Di Meglio
23341937766981423c9252e12e3319b2e7532739627Fabrice Di Meglio    @Override
234e9cb75c636234e44c94b38a877f3c60091d907dcFabrice Di Meglio    public void onClick(View v) {
2359c32468cd59cbe5b8e7692235a67034c936b4788Sudheer Shanka        if (mDisabledByAdmin) {
236aa71afe5978b1340a2d702f3a75d22baf8c96348Fan Zhang            mMetricsFeatureProvider.count(mContext, mMetricsTag + "/switch_bar|restricted", 1);
2379c32468cd59cbe5b8e7692235a67034c936b4788Sudheer Shanka            RestrictedLockUtils.sendShowAdminSupportDetailsIntent(mContext, mEnforcedAdmin);
2389c32468cd59cbe5b8e7692235a67034c936b4788Sudheer Shanka        } else {
2399c32468cd59cbe5b8e7692235a67034c936b4788Sudheer Shanka            final boolean isChecked = !mSwitch.isChecked();
2409c32468cd59cbe5b8e7692235a67034c936b4788Sudheer Shanka            setChecked(isChecked);
2419c32468cd59cbe5b8e7692235a67034c936b4788Sudheer Shanka        }
242e9cb75c636234e44c94b38a877f3c60091d907dcFabrice Di Meglio    }
243e9cb75c636234e44c94b38a877f3c60091d907dcFabrice Di Meglio
244e9cb75c636234e44c94b38a877f3c60091d907dcFabrice Di Meglio    public void propagateChecked(boolean isChecked) {
24541937766981423c9252e12e3319b2e7532739627Fabrice Di Meglio        final int count = mSwitchChangeListeners.size();
24641937766981423c9252e12e3319b2e7532739627Fabrice Di Meglio        for (int n = 0; n < count; n++) {
247e9cb75c636234e44c94b38a877f3c60091d907dcFabrice Di Meglio            mSwitchChangeListeners.get(n).onSwitchChanged(mSwitch, isChecked);
24841937766981423c9252e12e3319b2e7532739627Fabrice Di Meglio        }
24941937766981423c9252e12e3319b2e7532739627Fabrice Di Meglio    }
25041937766981423c9252e12e3319b2e7532739627Fabrice Di Meglio
251e9cb75c636234e44c94b38a877f3c60091d907dcFabrice Di Meglio    @Override
252e9cb75c636234e44c94b38a877f3c60091d907dcFabrice Di Meglio    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
2536d2a0c80df01a95adccfbb5926b1c463b60f6366Fan Zhang        if (mLoggingIntialized) {
254aa71afe5978b1340a2d702f3a75d22baf8c96348Fan Zhang            mMetricsFeatureProvider.count(mContext, mMetricsTag + "/switch_bar|" + isChecked, 1);
2556d2a0c80df01a95adccfbb5926b1c463b60f6366Fan Zhang        }
2566d2a0c80df01a95adccfbb5926b1c463b60f6366Fan Zhang        mLoggingIntialized = true;
257e9cb75c636234e44c94b38a877f3c60091d907dcFabrice Di Meglio        propagateChecked(isChecked);
258e9cb75c636234e44c94b38a877f3c60091d907dcFabrice Di Meglio    }
259e9cb75c636234e44c94b38a877f3c60091d907dcFabrice Di Meglio
26041937766981423c9252e12e3319b2e7532739627Fabrice Di Meglio    public void addOnSwitchChangeListener(OnSwitchChangeListener listener) {
26141937766981423c9252e12e3319b2e7532739627Fabrice Di Meglio        if (mSwitchChangeListeners.contains(listener)) {
26241937766981423c9252e12e3319b2e7532739627Fabrice Di Meglio            throw new IllegalStateException("Cannot add twice the same OnSwitchChangeListener");
26341937766981423c9252e12e3319b2e7532739627Fabrice Di Meglio        }
26441937766981423c9252e12e3319b2e7532739627Fabrice Di Meglio        mSwitchChangeListeners.add(listener);
26541937766981423c9252e12e3319b2e7532739627Fabrice Di Meglio    }
26641937766981423c9252e12e3319b2e7532739627Fabrice Di Meglio
26741937766981423c9252e12e3319b2e7532739627Fabrice Di Meglio    public void removeOnSwitchChangeListener(OnSwitchChangeListener listener) {
26841937766981423c9252e12e3319b2e7532739627Fabrice Di Meglio        if (!mSwitchChangeListeners.contains(listener)) {
26941937766981423c9252e12e3319b2e7532739627Fabrice Di Meglio            throw new IllegalStateException("Cannot remove OnSwitchChangeListener");
27041937766981423c9252e12e3319b2e7532739627Fabrice Di Meglio        }
27141937766981423c9252e12e3319b2e7532739627Fabrice Di Meglio        mSwitchChangeListeners.remove(listener);
27241937766981423c9252e12e3319b2e7532739627Fabrice Di Meglio    }
273138ff8c0457c6e1345015973668d652fa17c7c3bFabrice Di Meglio
274138ff8c0457c6e1345015973668d652fa17c7c3bFabrice Di Meglio    static class SavedState extends BaseSavedState {
275138ff8c0457c6e1345015973668d652fa17c7c3bFabrice Di Meglio        boolean checked;
276138ff8c0457c6e1345015973668d652fa17c7c3bFabrice Di Meglio        boolean visible;
277138ff8c0457c6e1345015973668d652fa17c7c3bFabrice Di Meglio
278138ff8c0457c6e1345015973668d652fa17c7c3bFabrice Di Meglio        SavedState(Parcelable superState) {
279138ff8c0457c6e1345015973668d652fa17c7c3bFabrice Di Meglio            super(superState);
280138ff8c0457c6e1345015973668d652fa17c7c3bFabrice Di Meglio        }
281138ff8c0457c6e1345015973668d652fa17c7c3bFabrice Di Meglio
282138ff8c0457c6e1345015973668d652fa17c7c3bFabrice Di Meglio        /**
283138ff8c0457c6e1345015973668d652fa17c7c3bFabrice Di Meglio         * Constructor called from {@link #CREATOR}
284138ff8c0457c6e1345015973668d652fa17c7c3bFabrice Di Meglio         */
285138ff8c0457c6e1345015973668d652fa17c7c3bFabrice Di Meglio        private SavedState(Parcel in) {
286138ff8c0457c6e1345015973668d652fa17c7c3bFabrice Di Meglio            super(in);
287138ff8c0457c6e1345015973668d652fa17c7c3bFabrice Di Meglio            checked = (Boolean)in.readValue(null);
288138ff8c0457c6e1345015973668d652fa17c7c3bFabrice Di Meglio            visible = (Boolean)in.readValue(null);
289138ff8c0457c6e1345015973668d652fa17c7c3bFabrice Di Meglio        }
290138ff8c0457c6e1345015973668d652fa17c7c3bFabrice Di Meglio
291138ff8c0457c6e1345015973668d652fa17c7c3bFabrice Di Meglio        @Override
292138ff8c0457c6e1345015973668d652fa17c7c3bFabrice Di Meglio        public void writeToParcel(Parcel out, int flags) {
293138ff8c0457c6e1345015973668d652fa17c7c3bFabrice Di Meglio            super.writeToParcel(out, flags);
294138ff8c0457c6e1345015973668d652fa17c7c3bFabrice Di Meglio            out.writeValue(checked);
295138ff8c0457c6e1345015973668d652fa17c7c3bFabrice Di Meglio            out.writeValue(visible);
296138ff8c0457c6e1345015973668d652fa17c7c3bFabrice Di Meglio        }
297138ff8c0457c6e1345015973668d652fa17c7c3bFabrice Di Meglio
298138ff8c0457c6e1345015973668d652fa17c7c3bFabrice Di Meglio        @Override
299138ff8c0457c6e1345015973668d652fa17c7c3bFabrice Di Meglio        public String toString() {
300138ff8c0457c6e1345015973668d652fa17c7c3bFabrice Di Meglio            return "SwitchBar.SavedState{"
301138ff8c0457c6e1345015973668d652fa17c7c3bFabrice Di Meglio                    + Integer.toHexString(System.identityHashCode(this))
302138ff8c0457c6e1345015973668d652fa17c7c3bFabrice Di Meglio                    + " checked=" + checked
303138ff8c0457c6e1345015973668d652fa17c7c3bFabrice Di Meglio                    + " visible=" + visible + "}";
304138ff8c0457c6e1345015973668d652fa17c7c3bFabrice Di Meglio        }
305138ff8c0457c6e1345015973668d652fa17c7c3bFabrice Di Meglio
306138ff8c0457c6e1345015973668d652fa17c7c3bFabrice Di Meglio        public static final Parcelable.Creator<SavedState> CREATOR
307138ff8c0457c6e1345015973668d652fa17c7c3bFabrice Di Meglio                = new Parcelable.Creator<SavedState>() {
308138ff8c0457c6e1345015973668d652fa17c7c3bFabrice Di Meglio            public SavedState createFromParcel(Parcel in) {
309138ff8c0457c6e1345015973668d652fa17c7c3bFabrice Di Meglio                return new SavedState(in);
310138ff8c0457c6e1345015973668d652fa17c7c3bFabrice Di Meglio            }
311138ff8c0457c6e1345015973668d652fa17c7c3bFabrice Di Meglio
312138ff8c0457c6e1345015973668d652fa17c7c3bFabrice Di Meglio            public SavedState[] newArray(int size) {
313138ff8c0457c6e1345015973668d652fa17c7c3bFabrice Di Meglio                return new SavedState[size];
314138ff8c0457c6e1345015973668d652fa17c7c3bFabrice Di Meglio            }
315138ff8c0457c6e1345015973668d652fa17c7c3bFabrice Di Meglio        };
316138ff8c0457c6e1345015973668d652fa17c7c3bFabrice Di Meglio    }
317138ff8c0457c6e1345015973668d652fa17c7c3bFabrice Di Meglio
318138ff8c0457c6e1345015973668d652fa17c7c3bFabrice Di Meglio    @Override
319138ff8c0457c6e1345015973668d652fa17c7c3bFabrice Di Meglio    public Parcelable onSaveInstanceState() {
320138ff8c0457c6e1345015973668d652fa17c7c3bFabrice Di Meglio        Parcelable superState = super.onSaveInstanceState();
321138ff8c0457c6e1345015973668d652fa17c7c3bFabrice Di Meglio
322138ff8c0457c6e1345015973668d652fa17c7c3bFabrice Di Meglio        SavedState ss = new SavedState(superState);
323138ff8c0457c6e1345015973668d652fa17c7c3bFabrice Di Meglio        ss.checked = mSwitch.isChecked();
324138ff8c0457c6e1345015973668d652fa17c7c3bFabrice Di Meglio        ss.visible = isShowing();
325138ff8c0457c6e1345015973668d652fa17c7c3bFabrice Di Meglio        return ss;
326138ff8c0457c6e1345015973668d652fa17c7c3bFabrice Di Meglio    }
327138ff8c0457c6e1345015973668d652fa17c7c3bFabrice Di Meglio
328138ff8c0457c6e1345015973668d652fa17c7c3bFabrice Di Meglio    @Override
329138ff8c0457c6e1345015973668d652fa17c7c3bFabrice Di Meglio    public void onRestoreInstanceState(Parcelable state) {
330138ff8c0457c6e1345015973668d652fa17c7c3bFabrice Di Meglio        SavedState ss = (SavedState) state;
331138ff8c0457c6e1345015973668d652fa17c7c3bFabrice Di Meglio
332138ff8c0457c6e1345015973668d652fa17c7c3bFabrice Di Meglio        super.onRestoreInstanceState(ss.getSuperState());
333d2b1e441b7314640b2c51ca367c6cc3925147a81Fabrice Di Meglio
334d2b1e441b7314640b2c51ca367c6cc3925147a81Fabrice Di Meglio        mSwitch.setCheckedInternal(ss.checked);
335138ff8c0457c6e1345015973668d652fa17c7c3bFabrice Di Meglio        setTextViewLabel(ss.checked);
336138ff8c0457c6e1345015973668d652fa17c7c3bFabrice Di Meglio        setVisibility(ss.visible ? View.VISIBLE : View.GONE);
337d2b1e441b7314640b2c51ca367c6cc3925147a81Fabrice Di Meglio        mSwitch.setOnCheckedChangeListener(ss.visible ? this : null);
338d2b1e441b7314640b2c51ca367c6cc3925147a81Fabrice Di Meglio
339138ff8c0457c6e1345015973668d652fa17c7c3bFabrice Di Meglio        requestLayout();
340138ff8c0457c6e1345015973668d652fa17c7c3bFabrice Di Meglio    }
341c99d0a8a797aba4ec75ffdc766a3ca131ab84103Maxim Bogatov
342e88a05601c1a69ca77b05eaab4cc10a0efdf1e05Anna Galusza    @Override
343e88a05601c1a69ca77b05eaab4cc10a0efdf1e05Anna Galusza    public CharSequence getAccessibilityClassName() {
344e88a05601c1a69ca77b05eaab4cc10a0efdf1e05Anna Galusza        return Switch.class.getName();
345e88a05601c1a69ca77b05eaab4cc10a0efdf1e05Anna Galusza    }
346e88a05601c1a69ca77b05eaab4cc10a0efdf1e05Anna Galusza
347664f6dacca97281e852bbb7fd8094a329d299d9aPhil Weaver    @Override
348664f6dacca97281e852bbb7fd8094a329d299d9aPhil Weaver    public boolean onRequestSendAccessibilityEvent(View child, AccessibilityEvent event) {
349664f6dacca97281e852bbb7fd8094a329d299d9aPhil Weaver        // Since the children are marked as not important for accessibility, re-dispatch all
350664f6dacca97281e852bbb7fd8094a329d299d9aPhil Weaver        // of their events as if they came from this view
351664f6dacca97281e852bbb7fd8094a329d299d9aPhil Weaver        event.setSource(this);
352664f6dacca97281e852bbb7fd8094a329d299d9aPhil Weaver        return true;
353664f6dacca97281e852bbb7fd8094a329d299d9aPhil Weaver    }
354664f6dacca97281e852bbb7fd8094a329d299d9aPhil Weaver
355c99d0a8a797aba4ec75ffdc766a3ca131ab84103Maxim Bogatov    /** @hide */
356c99d0a8a797aba4ec75ffdc766a3ca131ab84103Maxim Bogatov    @Override
357c99d0a8a797aba4ec75ffdc766a3ca131ab84103Maxim Bogatov    public void onInitializeAccessibilityNodeInfoInternal(AccessibilityNodeInfo info) {
358c99d0a8a797aba4ec75ffdc766a3ca131ab84103Maxim Bogatov        super.onInitializeAccessibilityNodeInfoInternal(info);
359c99d0a8a797aba4ec75ffdc766a3ca131ab84103Maxim Bogatov        info.setText(mTextView.getText());
360c99d0a8a797aba4ec75ffdc766a3ca131ab84103Maxim Bogatov        info.setCheckable(true);
361c99d0a8a797aba4ec75ffdc766a3ca131ab84103Maxim Bogatov        info.setChecked(mSwitch.isChecked());
362c99d0a8a797aba4ec75ffdc766a3ca131ab84103Maxim Bogatov    }
363c99d0a8a797aba4ec75ffdc766a3ca131ab84103Maxim Bogatov
364c99d0a8a797aba4ec75ffdc766a3ca131ab84103Maxim Bogatov    /** @hide */
365c99d0a8a797aba4ec75ffdc766a3ca131ab84103Maxim Bogatov    @Override
366c99d0a8a797aba4ec75ffdc766a3ca131ab84103Maxim Bogatov    public void onInitializeAccessibilityEventInternal(AccessibilityEvent event) {
367c99d0a8a797aba4ec75ffdc766a3ca131ab84103Maxim Bogatov        super.onInitializeAccessibilityEventInternal(event);
368e88a05601c1a69ca77b05eaab4cc10a0efdf1e05Anna Galusza        // Don't say "on on" or "off off" - rather, speak the state only once. We need to specify
369e88a05601c1a69ca77b05eaab4cc10a0efdf1e05Anna Galusza        // this explicitly as each of our children (the textview and the checkbox) contribute to
370e88a05601c1a69ca77b05eaab4cc10a0efdf1e05Anna Galusza        // the state once, giving us duplicate text by default.
371e88a05601c1a69ca77b05eaab4cc10a0efdf1e05Anna Galusza        event.setContentDescription(mTextView.getText());
372c99d0a8a797aba4ec75ffdc766a3ca131ab84103Maxim Bogatov        event.setChecked(mSwitch.isChecked());
373c99d0a8a797aba4ec75ffdc766a3ca131ab84103Maxim Bogatov    }
37441937766981423c9252e12e3319b2e7532739627Fabrice Di Meglio}
375