1/*
2 * Copyright (C) 2014 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.settings.notification;
18
19import android.animation.LayoutTransition;
20import android.app.INotificationManager;
21import android.content.Context;
22import android.net.Uri;
23import android.os.Handler;
24import android.os.Message;
25import android.os.RemoteException;
26import android.os.ServiceManager;
27import android.service.notification.Condition;
28import android.service.notification.IConditionListener;
29import android.util.ArraySet;
30import android.util.Log;
31import android.widget.CheckBox;
32import android.widget.CompoundButton;
33import android.widget.LinearLayout;
34
35import com.android.settings.R;
36
37public class ZenModeAutomaticConditionSelection extends LinearLayout {
38    private static final String TAG = "ZenModeAutomaticConditionSelection";
39    private static final boolean DEBUG = true;
40
41    private final INotificationManager mNoMan;
42    private final H mHandler = new H();
43    private final Context mContext;
44    private final ArraySet<Uri> mSelectedConditions = new ArraySet<Uri>();
45
46    public ZenModeAutomaticConditionSelection(Context context) {
47        super(context);
48        mContext = context;
49        setOrientation(VERTICAL);
50        setLayoutTransition(new LayoutTransition());
51        final int p = mContext.getResources().getDimensionPixelSize(R.dimen.content_margin_left);
52        setPadding(p, p, p, 0);
53        mNoMan = INotificationManager.Stub.asInterface(
54                ServiceManager.getService(Context.NOTIFICATION_SERVICE));
55        refreshSelectedConditions();
56    }
57
58    private void refreshSelectedConditions() {
59        try {
60            final Condition[] automatic = mNoMan.getAutomaticZenModeConditions();
61            mSelectedConditions.clear();
62            if (automatic != null) {
63                for (Condition c : automatic) {
64                    mSelectedConditions.add(c.id);
65                }
66            }
67        } catch (RemoteException e) {
68            Log.w(TAG, "Error calling getAutomaticZenModeConditions", e);
69        }
70    }
71
72    private CheckBox newCheckBox(Object tag) {
73        final CheckBox button = new CheckBox(mContext);
74        button.setTag(tag);
75        button.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
76            @Override
77            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
78                 setSelectedCondition((Uri)button.getTag(), isChecked);
79            }
80        });
81        addView(button);
82        return button;
83    }
84
85    private void setSelectedCondition(Uri conditionId, boolean selected) {
86        if (DEBUG) Log.d(TAG, "setSelectedCondition conditionId=" + conditionId
87                + " selected=" + selected);
88        if (selected) {
89            mSelectedConditions.add(conditionId);
90        } else {
91            mSelectedConditions.remove(conditionId);
92        }
93        final Uri[] automatic = new Uri[mSelectedConditions.size()];
94        for (int i = 0; i < automatic.length; i++) {
95            automatic[i] = mSelectedConditions.valueAt(i);
96        }
97        try {
98            mNoMan.setAutomaticZenModeConditions(automatic);
99        } catch (RemoteException e) {
100            Log.w(TAG, "Error calling setAutomaticZenModeConditions", e);
101        }
102    }
103
104    @Override
105    protected void onAttachedToWindow() {
106        super.onAttachedToWindow();
107        requestZenModeConditions(Condition.FLAG_RELEVANT_ALWAYS);
108    }
109
110    @Override
111    protected void onDetachedFromWindow() {
112        super.onDetachedFromWindow();
113        requestZenModeConditions(0 /*none*/);
114    }
115
116    protected void requestZenModeConditions(int relevance) {
117        if (DEBUG) Log.d(TAG, "requestZenModeConditions " + Condition.relevanceToString(relevance));
118        try {
119            mNoMan.requestZenModeConditions(mListener, relevance);
120        } catch (RemoteException e) {
121            Log.w(TAG, "Error calling requestZenModeConditions", e);
122        }
123    }
124
125    protected void handleConditions(Condition[] conditions) {
126        for (final Condition c : conditions) {
127            CheckBox v = (CheckBox) findViewWithTag(c.id);
128            if (c.state != Condition.STATE_ERROR) {
129                if (v == null) {
130                    v = newCheckBox(c.id);
131                }
132            }
133            if (v != null) {
134                v.setText(c.summary);
135                v.setEnabled(c.state != Condition.STATE_ERROR);
136                v.setChecked(mSelectedConditions.contains(c.id));
137            }
138        }
139    }
140
141    private final IConditionListener mListener = new IConditionListener.Stub() {
142        @Override
143        public void onConditionsReceived(Condition[] conditions) {
144            if (conditions == null || conditions.length == 0) return;
145            mHandler.obtainMessage(H.CONDITIONS, conditions).sendToTarget();
146        }
147    };
148
149    private final class H extends Handler {
150        private static final int CONDITIONS = 1;
151
152        @Override
153        public void handleMessage(Message msg) {
154            if (msg.what == CONDITIONS) handleConditions((Condition[])msg.obj);
155        }
156    }
157}
158