IntentTile.java revision bceed060f0090a4f86418c4515128d5ec8ebdd4a
1bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock/*
2bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock * Copyright (C) 2014 The Android Open Source Project
3bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock *
4bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock * Licensed under the Apache License, Version 2.0 (the "License");
5bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock * you may not use this file except in compliance with the License.
6bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock * You may obtain a copy of the License at
7bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock *
8bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock *      http://www.apache.org/licenses/LICENSE-2.0
9bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock *
10bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock * Unless required by applicable law or agreed to in writing, software
11bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock * distributed under the License is distributed on an "AS IS" BASIS,
12bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock * See the License for the specific language governing permissions and
14bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock * limitations under the License.
15bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock */
16bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock
17bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlockpackage com.android.systemui.qs.tiles;
18bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock
19bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlockimport android.app.PendingIntent;
20bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlockimport android.content.BroadcastReceiver;
21bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlockimport android.content.Context;
22bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlockimport android.content.Intent;
23bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlockimport android.content.IntentFilter;
24bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlockimport android.graphics.Bitmap;
25bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlockimport android.graphics.BitmapFactory;
26bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlockimport android.graphics.drawable.BitmapDrawable;
27bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlockimport android.graphics.drawable.Drawable;
28bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlockimport android.os.UserHandle;
29bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlockimport android.text.TextUtils;
30bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlockimport android.util.Log;
31bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock
32bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlockimport com.android.systemui.qs.QSTile;
33bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock
34bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlockpublic class IntentTile extends QSTile<QSTile.State> {
35bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock    public static final String PREFIX = "intent(";
36bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock
37bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock    private PendingIntent mOnClick;
38bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock    private String mOnClickUri;
39bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock    private int mCurrentUserId;
40bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock
41bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock    private IntentTile(Host host, String action) {
42bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock        super(host);
43bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock        mContext.registerReceiver(mReceiver, new IntentFilter(action));
44bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock    }
45bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock
46bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock    @Override
47bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock    protected void handleDestroy() {
48bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock        super.handleDestroy();
49bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock        mContext.unregisterReceiver(mReceiver);
50bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock    }
51bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock
52bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock    public static QSTile<?> create(Host host, String spec) {
53bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock        if (spec == null || !spec.startsWith(PREFIX) || !spec.endsWith(")")) {
54bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock            throw new IllegalArgumentException("Bad intent tile spec: " + spec);
55bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock        }
56bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock        final String action = spec.substring(PREFIX.length(), spec.length() - 1);
57bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock        if (action.isEmpty()) {
58bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock            throw new IllegalArgumentException("Empty intent tile spec action");
59bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock        }
60bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock        return new IntentTile(host, action);
61bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock    }
62bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock
63bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock    @Override
64bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock    public void setListening(boolean listening) {
65bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock    }
66bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock
67bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock    @Override
68bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock    protected State newTileState() {
69bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock        return new State();
70bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock    }
71bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock
72bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock    @Override
73bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock    protected void handleUserSwitch(int newUserId) {
74bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock        super.handleUserSwitch(newUserId);
75bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock        mCurrentUserId = newUserId;
76bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock    }
77bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock
78bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock    @Override
79bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock    protected void handleClick() {
80bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock        try {
81bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock            if (mOnClick != null) {
82bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock                mOnClick.send();
83bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock            } else if (mOnClickUri != null) {
84bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock                final Intent intent = Intent.parseUri(mOnClickUri, Intent.URI_INTENT_SCHEME);
85bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock                mContext.sendBroadcastAsUser(intent, new UserHandle(mCurrentUserId));
86bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock            }
87bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock        } catch (Throwable t) {
88bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock            Log.w(TAG, "Error sending click intent", t);
89bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock        }
90bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock    }
91bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock
92bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock    @Override
93bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock    protected void handleUpdateState(State state, Object arg) {
94bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock        if (!(arg instanceof Intent)) return;
95bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock        final Intent intent = (Intent) arg;
96bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock        state.visible = intent.getBooleanExtra("visible", true);
97bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock        state.contentDescription = intent.getStringExtra("contentDescription");
98bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock        state.label = intent.getStringExtra("label");
99bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock        state.iconId = 0;
100bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock        state.icon = null;
101bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock        final byte[] iconBitmap = intent.getByteArrayExtra("iconBitmap");
102bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock        if (iconBitmap != null) {
103bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock            try {
104bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock                final Bitmap b = BitmapFactory.decodeByteArray(iconBitmap, 0, iconBitmap.length);
105bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock                state.icon = new BitmapDrawable(mContext.getResources(), b);
106bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock            } catch (Throwable t) {
107bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock                Log.w(TAG, "Error loading icon bitmap, length " + iconBitmap.length, t);
108bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock            }
109bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock        } else {
110bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock            final int iconId = intent.getIntExtra("iconId", 0);
111bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock            if (iconId != 0) {
112bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock                final String iconPackage = intent.getStringExtra("iconPackage");
113bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock                if (!TextUtils.isEmpty(iconPackage)) {
114bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock                    state.icon = getPackageDrawable(iconPackage, iconId);
115bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock                } else {
116bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock                    state.iconId = iconId;
117bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock                }
118bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock            }
119bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock        }
120bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock        mOnClick = intent.getParcelableExtra("onClick");
121bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock        mOnClickUri = intent.getStringExtra("onClickUri");
122bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock    }
123bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock
124bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock    private Drawable getPackageDrawable(String pkg, int id) {
125bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock        try {
126bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock            return mContext.createPackageContext(pkg, 0).getDrawable(id);
127bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock        } catch (Throwable t) {
128bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock            Log.w(TAG, "Error loading package drawable pkg=" + pkg + " id=" + id, t);
129bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock            return null;
130bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock        }
131bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock    }
132bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock
133bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
134bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock        @Override
135bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock        public void onReceive(Context context, Intent intent) {
136bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock            refreshState(intent);
137bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock        }
138bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock    };
139bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock}
140