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