IntentTile.java revision bceed060f0090a4f86418c4515128d5ec8ebdd4a
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.systemui.qs.tiles;
18
19import android.app.PendingIntent;
20import android.content.BroadcastReceiver;
21import android.content.Context;
22import android.content.Intent;
23import android.content.IntentFilter;
24import android.graphics.Bitmap;
25import android.graphics.BitmapFactory;
26import android.graphics.drawable.BitmapDrawable;
27import android.graphics.drawable.Drawable;
28import android.os.UserHandle;
29import android.text.TextUtils;
30import android.util.Log;
31
32import com.android.systemui.qs.QSTile;
33
34public class IntentTile extends QSTile<QSTile.State> {
35    public static final String PREFIX = "intent(";
36
37    private PendingIntent mOnClick;
38    private String mOnClickUri;
39    private int mCurrentUserId;
40
41    private IntentTile(Host host, String action) {
42        super(host);
43        mContext.registerReceiver(mReceiver, new IntentFilter(action));
44    }
45
46    @Override
47    protected void handleDestroy() {
48        super.handleDestroy();
49        mContext.unregisterReceiver(mReceiver);
50    }
51
52    public static QSTile<?> create(Host host, String spec) {
53        if (spec == null || !spec.startsWith(PREFIX) || !spec.endsWith(")")) {
54            throw new IllegalArgumentException("Bad intent tile spec: " + spec);
55        }
56        final String action = spec.substring(PREFIX.length(), spec.length() - 1);
57        if (action.isEmpty()) {
58            throw new IllegalArgumentException("Empty intent tile spec action");
59        }
60        return new IntentTile(host, action);
61    }
62
63    @Override
64    public void setListening(boolean listening) {
65    }
66
67    @Override
68    protected State newTileState() {
69        return new State();
70    }
71
72    @Override
73    protected void handleUserSwitch(int newUserId) {
74        super.handleUserSwitch(newUserId);
75        mCurrentUserId = newUserId;
76    }
77
78    @Override
79    protected void handleClick() {
80        try {
81            if (mOnClick != null) {
82                mOnClick.send();
83            } else if (mOnClickUri != null) {
84                final Intent intent = Intent.parseUri(mOnClickUri, Intent.URI_INTENT_SCHEME);
85                mContext.sendBroadcastAsUser(intent, new UserHandle(mCurrentUserId));
86            }
87        } catch (Throwable t) {
88            Log.w(TAG, "Error sending click intent", t);
89        }
90    }
91
92    @Override
93    protected void handleUpdateState(State state, Object arg) {
94        if (!(arg instanceof Intent)) return;
95        final Intent intent = (Intent) arg;
96        state.visible = intent.getBooleanExtra("visible", true);
97        state.contentDescription = intent.getStringExtra("contentDescription");
98        state.label = intent.getStringExtra("label");
99        state.iconId = 0;
100        state.icon = null;
101        final byte[] iconBitmap = intent.getByteArrayExtra("iconBitmap");
102        if (iconBitmap != null) {
103            try {
104                final Bitmap b = BitmapFactory.decodeByteArray(iconBitmap, 0, iconBitmap.length);
105                state.icon = new BitmapDrawable(mContext.getResources(), b);
106            } catch (Throwable t) {
107                Log.w(TAG, "Error loading icon bitmap, length " + iconBitmap.length, t);
108            }
109        } else {
110            final int iconId = intent.getIntExtra("iconId", 0);
111            if (iconId != 0) {
112                final String iconPackage = intent.getStringExtra("iconPackage");
113                if (!TextUtils.isEmpty(iconPackage)) {
114                    state.icon = getPackageDrawable(iconPackage, iconId);
115                } else {
116                    state.iconId = iconId;
117                }
118            }
119        }
120        mOnClick = intent.getParcelableExtra("onClick");
121        mOnClickUri = intent.getStringExtra("onClickUri");
122    }
123
124    private Drawable getPackageDrawable(String pkg, int id) {
125        try {
126            return mContext.createPackageContext(pkg, 0).getDrawable(id);
127        } catch (Throwable t) {
128            Log.w(TAG, "Error loading package drawable pkg=" + pkg + " id=" + id, t);
129            return null;
130        }
131    }
132
133    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
134        @Override
135        public void onReceive(Context context, Intent intent) {
136            refreshState(intent);
137        }
138    };
139}
140