1/*
2 * Copyright (C) 2015 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 */
16package android.service.quicksettings;
17
18import android.graphics.drawable.Icon;
19import android.os.IBinder;
20import android.os.Parcel;
21import android.os.Parcelable;
22import android.os.RemoteException;
23import android.text.TextUtils;
24import android.util.Log;
25
26/**
27 * A Tile holds the state of a tile that will be displayed
28 * in Quick Settings.
29 *
30 * A tile in Quick Settings exists as an icon with an accompanied label.
31 * It also may have content description for accessibility usability.
32 * The style and layout of the tile may change to match a given
33 * device.
34 */
35public final class Tile implements Parcelable {
36
37    private static final String TAG = "Tile";
38
39    /**
40     * An unavailable state indicates that for some reason this tile is not currently
41     * available to the user for some reason, and will have no click action.  The tile's
42     * icon will be tinted differently to reflect this state.
43     */
44    public static final int STATE_UNAVAILABLE = 0;
45
46    /**
47     * This represents a tile that is currently in a disabled state but is still interactable.
48     *
49     * A disabled state indicates that the tile is not currently active (e.g. wifi disconnected or
50     * bluetooth disabled), but is still interactable by the user to modify this state.  Tiles
51     * that have boolean states should use this to represent one of their states.  The tile's
52     * icon will be tinted differently to reflect this state, but still be distinct from unavailable.
53     */
54    public static final int STATE_INACTIVE = 1;
55
56    /**
57     * This represents a tile that is currently active. (e.g. wifi is connected, bluetooth is on,
58     * cast is casting).  This is the default state.
59     */
60    public static final int STATE_ACTIVE = 2;
61
62    private IBinder mToken;
63    private Icon mIcon;
64    private CharSequence mLabel;
65    private CharSequence mContentDescription;
66    // Default to active until clients of the new API can update.
67    private int mState = STATE_ACTIVE;
68
69    private IQSService mService;
70
71    /**
72     * @hide
73     */
74    public Tile(Parcel source) {
75        readFromParcel(source);
76    }
77
78    /**
79     * @hide
80     */
81    public Tile() {
82    }
83
84    /**
85     * @hide
86     */
87    public void setService(IQSService service, IBinder stub) {
88        mService = service;
89        mToken = stub;
90    }
91
92    /**
93     * The current state of the tile.
94     *
95     * @see #STATE_UNAVAILABLE
96     * @see #STATE_INACTIVE
97     * @see #STATE_ACTIVE
98     */
99    public int getState() {
100        return mState;
101    }
102
103    /**
104     * Sets the current state for the tile.
105     *
106     * Does not take effect until {@link #updateTile()} is called.
107     *
108     * @param state One of {@link #STATE_UNAVAILABLE}, {@link #STATE_INACTIVE},
109     * {@link #STATE_ACTIVE}
110     */
111    public void setState(int state) {
112        mState = state;
113    }
114
115    /**
116     * Gets the current icon for the tile.
117     */
118    public Icon getIcon() {
119        return mIcon;
120    }
121
122    /**
123     * Sets the current icon for the tile.
124     *
125     * This icon is expected to be white on alpha, and may be
126     * tinted by the system to match it's theme.
127     *
128     * Does not take effect until {@link #updateTile()} is called.
129     *
130     * @param icon New icon to show.
131     */
132    public void setIcon(Icon icon) {
133        this.mIcon = icon;
134    }
135
136    /**
137     * Gets the current label for the tile.
138     */
139    public CharSequence getLabel() {
140        return mLabel;
141    }
142
143    /**
144     * Sets the current label for the tile.
145     *
146     * Does not take effect until {@link #updateTile()} is called.
147     *
148     * @param label New label to show.
149     */
150    public void setLabel(CharSequence label) {
151        this.mLabel = label;
152    }
153
154    /**
155     * Gets the current content description for the tile.
156     */
157    public CharSequence getContentDescription() {
158        return mContentDescription;
159    }
160
161    /**
162     * Sets the current content description for the tile.
163     *
164     * Does not take effect until {@link #updateTile()} is called.
165     *
166     * @param contentDescription New content description to use.
167     */
168    public void setContentDescription(CharSequence contentDescription) {
169        this.mContentDescription = contentDescription;
170    }
171
172    @Override
173    public int describeContents() {
174        return 0;
175    }
176
177    /**
178     * Pushes the state of the Tile to Quick Settings to be displayed.
179     */
180    public void updateTile() {
181        try {
182            mService.updateQsTile(this, mToken);
183        } catch (RemoteException e) {
184            Log.e(TAG, "Couldn't update tile");
185        }
186    }
187
188    @Override
189    public void writeToParcel(Parcel dest, int flags) {
190        if (mIcon != null) {
191            dest.writeByte((byte) 1);
192            mIcon.writeToParcel(dest, flags);
193        } else {
194            dest.writeByte((byte) 0);
195        }
196        dest.writeInt(mState);
197        TextUtils.writeToParcel(mLabel, dest, flags);
198        TextUtils.writeToParcel(mContentDescription, dest, flags);
199    }
200
201    private void readFromParcel(Parcel source) {
202        if (source.readByte() != 0) {
203            mIcon = Icon.CREATOR.createFromParcel(source);
204        } else {
205            mIcon = null;
206        }
207        mState = source.readInt();
208        mLabel = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source);
209        mContentDescription = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source);
210    }
211
212    public static final Creator<Tile> CREATOR = new Creator<Tile>() {
213        @Override
214        public Tile createFromParcel(Parcel source) {
215            return new Tile(source);
216        }
217
218        @Override
219        public Tile[] newArray(int size) {
220            return new Tile[size];
221        }
222    };
223}