IntentTile.java revision 76c67aa361f65dfb2f5e03d06cc1ccebce9cecd9
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 32457a21cdeac04565a0c40ad8c43a928c1182ddd1Chris Wrenimport com.android.internal.logging.MetricsLogger; 33f6e9228b8a97603d3ceb8f0d61e8d87cf19bd21fChris Wrenimport com.android.internal.logging.MetricsProto.MetricsEvent; 34bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlockimport com.android.systemui.qs.QSTile; 35bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock 362d695813b44690ca146f95939acb00f0c14dac29John Spurlockimport java.util.Arrays; 372d695813b44690ca146f95939acb00f0c14dac29John Spurlockimport java.util.Objects; 382d695813b44690ca146f95939acb00f0c14dac29John Spurlock 39bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlockpublic class IntentTile extends QSTile<QSTile.State> { 40bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock public static final String PREFIX = "intent("; 41bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock 42bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock private PendingIntent mOnClick; 43bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock private String mOnClickUri; 44c247b8f7270dd70ecc36977fcc0530217879f665John Spurlock private PendingIntent mOnLongClick; 45c247b8f7270dd70ecc36977fcc0530217879f665John Spurlock private String mOnLongClickUri; 46bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock private int mCurrentUserId; 47457a21cdeac04565a0c40ad8c43a928c1182ddd1Chris Wren private String mIntentPackage; 48bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock 49878c093336b324962f1b659aa29c79caed75ef2fJason Monk private Intent mLastIntent; 50878c093336b324962f1b659aa29c79caed75ef2fJason Monk 51bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock private IntentTile(Host host, String action) { 52bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock super(host); 53bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock mContext.registerReceiver(mReceiver, new IntentFilter(action)); 54bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock } 55bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock 56bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock @Override 57bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock protected void handleDestroy() { 58bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock super.handleDestroy(); 59bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock mContext.unregisterReceiver(mReceiver); 60bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock } 61bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock 62bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock public static QSTile<?> create(Host host, String spec) { 63bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock if (spec == null || !spec.startsWith(PREFIX) || !spec.endsWith(")")) { 64bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock throw new IllegalArgumentException("Bad intent tile spec: " + spec); 65bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock } 66bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock final String action = spec.substring(PREFIX.length(), spec.length() - 1); 67bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock if (action.isEmpty()) { 68bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock throw new IllegalArgumentException("Empty intent tile spec action"); 69bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock } 70bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock return new IntentTile(host, action); 71bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock } 72bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock 73bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock @Override 74bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock public void setListening(boolean listening) { 75bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock } 76bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock 77bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock @Override 7862b63a02d7ca630e3ad39991ea6550cab57e5d22Jason Monk public State newTileState() { 79bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock return new State(); 80bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock } 81bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock 82bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock @Override 83bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock protected void handleUserSwitch(int newUserId) { 84bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock super.handleUserSwitch(newUserId); 85bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock mCurrentUserId = newUserId; 86bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock } 87bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock 88bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock @Override 89bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock protected void handleClick() { 909e7283f6a31bc2beb75c84c6173968a46582c563Chris Wren MetricsLogger.action(mContext, getMetricsCategory(), mIntentPackage); 91c247b8f7270dd70ecc36977fcc0530217879f665John Spurlock sendIntent("click", mOnClick, mOnClickUri); 92c247b8f7270dd70ecc36977fcc0530217879f665John Spurlock } 93c247b8f7270dd70ecc36977fcc0530217879f665John Spurlock 94c247b8f7270dd70ecc36977fcc0530217879f665John Spurlock @Override 9576c67aa361f65dfb2f5e03d06cc1ccebce9cecd9Jason Monk public Intent getLongClickIntent() { 9676c67aa361f65dfb2f5e03d06cc1ccebce9cecd9Jason Monk return null; 9776c67aa361f65dfb2f5e03d06cc1ccebce9cecd9Jason Monk } 9876c67aa361f65dfb2f5e03d06cc1ccebce9cecd9Jason Monk 9976c67aa361f65dfb2f5e03d06cc1ccebce9cecd9Jason Monk @Override 100c247b8f7270dd70ecc36977fcc0530217879f665John Spurlock protected void handleLongClick() { 101c247b8f7270dd70ecc36977fcc0530217879f665John Spurlock sendIntent("long-click", mOnLongClick, mOnLongClickUri); 102c247b8f7270dd70ecc36977fcc0530217879f665John Spurlock } 103c247b8f7270dd70ecc36977fcc0530217879f665John Spurlock 104c247b8f7270dd70ecc36977fcc0530217879f665John Spurlock private void sendIntent(String type, PendingIntent pi, String uri) { 105bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock try { 106c247b8f7270dd70ecc36977fcc0530217879f665John Spurlock if (pi != null) { 107ee43cdfa43b09a79e66d81f6673a79bc26427343Jason Monk if (pi.isActivity()) { 10862692b22fbb6146613635abea225f4049dae4873Adrian Roos getHost().startActivityDismissingKeyguard(pi); 109ee43cdfa43b09a79e66d81f6673a79bc26427343Jason Monk } else { 110ee43cdfa43b09a79e66d81f6673a79bc26427343Jason Monk pi.send(); 111ee43cdfa43b09a79e66d81f6673a79bc26427343Jason Monk } 112c247b8f7270dd70ecc36977fcc0530217879f665John Spurlock } else if (uri != null) { 113c247b8f7270dd70ecc36977fcc0530217879f665John Spurlock final Intent intent = Intent.parseUri(uri, Intent.URI_INTENT_SCHEME); 114bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock mContext.sendBroadcastAsUser(intent, new UserHandle(mCurrentUserId)); 115bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock } 116bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock } catch (Throwable t) { 117c247b8f7270dd70ecc36977fcc0530217879f665John Spurlock Log.w(TAG, "Error sending " + type + " intent", t); 118bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock } 119bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock } 120bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock 121bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock @Override 122bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock protected void handleUpdateState(State state, Object arg) { 123878c093336b324962f1b659aa29c79caed75ef2fJason Monk Intent intent = (Intent) arg; 124878c093336b324962f1b659aa29c79caed75ef2fJason Monk if (intent == null) { 125878c093336b324962f1b659aa29c79caed75ef2fJason Monk if (mLastIntent == null) { 126878c093336b324962f1b659aa29c79caed75ef2fJason Monk return; 127878c093336b324962f1b659aa29c79caed75ef2fJason Monk } 128878c093336b324962f1b659aa29c79caed75ef2fJason Monk // No intent but need to refresh state, just use the last one. 129878c093336b324962f1b659aa29c79caed75ef2fJason Monk intent = mLastIntent; 130878c093336b324962f1b659aa29c79caed75ef2fJason Monk } 131878c093336b324962f1b659aa29c79caed75ef2fJason Monk // Save the last one in case we need it later. 132878c093336b324962f1b659aa29c79caed75ef2fJason Monk mLastIntent = intent; 133bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock state.contentDescription = intent.getStringExtra("contentDescription"); 134bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock state.label = intent.getStringExtra("label"); 135bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock state.icon = null; 136bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock final byte[] iconBitmap = intent.getByteArrayExtra("iconBitmap"); 137bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock if (iconBitmap != null) { 138bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock try { 1392d695813b44690ca146f95939acb00f0c14dac29John Spurlock state.icon = new BytesIcon(iconBitmap); 140bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock } catch (Throwable t) { 141bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock Log.w(TAG, "Error loading icon bitmap, length " + iconBitmap.length, t); 142bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock } 143bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock } else { 144bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock final int iconId = intent.getIntExtra("iconId", 0); 145bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock if (iconId != 0) { 146bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock final String iconPackage = intent.getStringExtra("iconPackage"); 147bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock if (!TextUtils.isEmpty(iconPackage)) { 1482d695813b44690ca146f95939acb00f0c14dac29John Spurlock state.icon = new PackageDrawableIcon(iconPackage, iconId); 149bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock } else { 1502d695813b44690ca146f95939acb00f0c14dac29John Spurlock state.icon = ResourceIcon.get(iconId); 151bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock } 152bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock } 153bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock } 154bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock mOnClick = intent.getParcelableExtra("onClick"); 155bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock mOnClickUri = intent.getStringExtra("onClickUri"); 156c247b8f7270dd70ecc36977fcc0530217879f665John Spurlock mOnLongClick = intent.getParcelableExtra("onLongClick"); 157c247b8f7270dd70ecc36977fcc0530217879f665John Spurlock mOnLongClickUri = intent.getStringExtra("onLongClickUri"); 158457a21cdeac04565a0c40ad8c43a928c1182ddd1Chris Wren mIntentPackage = intent.getStringExtra("package"); 1599e7283f6a31bc2beb75c84c6173968a46582c563Chris Wren mIntentPackage = mIntentPackage == null ? "" : mIntentPackage; 160457a21cdeac04565a0c40ad8c43a928c1182ddd1Chris Wren } 161457a21cdeac04565a0c40ad8c43a928c1182ddd1Chris Wren 162457a21cdeac04565a0c40ad8c43a928c1182ddd1Chris Wren @Override 163457a21cdeac04565a0c40ad8c43a928c1182ddd1Chris Wren public int getMetricsCategory() { 164f6e9228b8a97603d3ceb8f0d61e8d87cf19bd21fChris Wren return MetricsEvent.QS_INTENT; 165457a21cdeac04565a0c40ad8c43a928c1182ddd1Chris Wren } 166457a21cdeac04565a0c40ad8c43a928c1182ddd1Chris Wren 167bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock private final BroadcastReceiver mReceiver = new BroadcastReceiver() { 168bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock @Override 169bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock public void onReceive(Context context, Intent intent) { 170bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock refreshState(intent); 171bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock } 172bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock }; 1732d695813b44690ca146f95939acb00f0c14dac29John Spurlock 1742d695813b44690ca146f95939acb00f0c14dac29John Spurlock private static class BytesIcon extends Icon { 1752d695813b44690ca146f95939acb00f0c14dac29John Spurlock private final byte[] mBytes; 1762d695813b44690ca146f95939acb00f0c14dac29John Spurlock 1772d695813b44690ca146f95939acb00f0c14dac29John Spurlock public BytesIcon(byte[] bytes) { 1782d695813b44690ca146f95939acb00f0c14dac29John Spurlock mBytes = bytes; 1792d695813b44690ca146f95939acb00f0c14dac29John Spurlock } 1802d695813b44690ca146f95939acb00f0c14dac29John Spurlock 1812d695813b44690ca146f95939acb00f0c14dac29John Spurlock @Override 1822d695813b44690ca146f95939acb00f0c14dac29John Spurlock public Drawable getDrawable(Context context) { 1832d695813b44690ca146f95939acb00f0c14dac29John Spurlock final Bitmap b = BitmapFactory.decodeByteArray(mBytes, 0, mBytes.length); 1842d695813b44690ca146f95939acb00f0c14dac29John Spurlock return new BitmapDrawable(context.getResources(), b); 1852d695813b44690ca146f95939acb00f0c14dac29John Spurlock } 1862d695813b44690ca146f95939acb00f0c14dac29John Spurlock 1872d695813b44690ca146f95939acb00f0c14dac29John Spurlock @Override 1882d695813b44690ca146f95939acb00f0c14dac29John Spurlock public boolean equals(Object o) { 1892d695813b44690ca146f95939acb00f0c14dac29John Spurlock return o instanceof BytesIcon && Arrays.equals(((BytesIcon) o).mBytes, mBytes); 1902d695813b44690ca146f95939acb00f0c14dac29John Spurlock } 1912d695813b44690ca146f95939acb00f0c14dac29John Spurlock 1922d695813b44690ca146f95939acb00f0c14dac29John Spurlock @Override 1932d695813b44690ca146f95939acb00f0c14dac29John Spurlock public String toString() { 1942d695813b44690ca146f95939acb00f0c14dac29John Spurlock return String.format("BytesIcon[len=%s]", mBytes.length); 1952d695813b44690ca146f95939acb00f0c14dac29John Spurlock } 1962d695813b44690ca146f95939acb00f0c14dac29John Spurlock } 1972d695813b44690ca146f95939acb00f0c14dac29John Spurlock 1982d695813b44690ca146f95939acb00f0c14dac29John Spurlock private class PackageDrawableIcon extends Icon { 1992d695813b44690ca146f95939acb00f0c14dac29John Spurlock private final String mPackage; 2002d695813b44690ca146f95939acb00f0c14dac29John Spurlock private final int mResId; 2012d695813b44690ca146f95939acb00f0c14dac29John Spurlock 2022d695813b44690ca146f95939acb00f0c14dac29John Spurlock public PackageDrawableIcon(String pkg, int resId) { 2032d695813b44690ca146f95939acb00f0c14dac29John Spurlock mPackage = pkg; 2042d695813b44690ca146f95939acb00f0c14dac29John Spurlock mResId = resId; 2052d695813b44690ca146f95939acb00f0c14dac29John Spurlock } 2062d695813b44690ca146f95939acb00f0c14dac29John Spurlock 2072d695813b44690ca146f95939acb00f0c14dac29John Spurlock @Override 2082d695813b44690ca146f95939acb00f0c14dac29John Spurlock public boolean equals(Object o) { 2092d695813b44690ca146f95939acb00f0c14dac29John Spurlock if (!(o instanceof PackageDrawableIcon)) return false; 2102d695813b44690ca146f95939acb00f0c14dac29John Spurlock final PackageDrawableIcon other = (PackageDrawableIcon) o; 2112d695813b44690ca146f95939acb00f0c14dac29John Spurlock return Objects.equals(other.mPackage, mPackage) && other.mResId == mResId; 2122d695813b44690ca146f95939acb00f0c14dac29John Spurlock } 2132d695813b44690ca146f95939acb00f0c14dac29John Spurlock 2142d695813b44690ca146f95939acb00f0c14dac29John Spurlock @Override 2152d695813b44690ca146f95939acb00f0c14dac29John Spurlock public Drawable getDrawable(Context context) { 2162d695813b44690ca146f95939acb00f0c14dac29John Spurlock try { 2172d695813b44690ca146f95939acb00f0c14dac29John Spurlock return context.createPackageContext(mPackage, 0).getDrawable(mResId); 2182d695813b44690ca146f95939acb00f0c14dac29John Spurlock } catch (Throwable t) { 2192d695813b44690ca146f95939acb00f0c14dac29John Spurlock Log.w(TAG, "Error loading package drawable pkg=" + mPackage + " id=" + mResId, t); 2202d695813b44690ca146f95939acb00f0c14dac29John Spurlock return null; 2212d695813b44690ca146f95939acb00f0c14dac29John Spurlock } 2222d695813b44690ca146f95939acb00f0c14dac29John Spurlock } 2232d695813b44690ca146f95939acb00f0c14dac29John Spurlock 2242d695813b44690ca146f95939acb00f0c14dac29John Spurlock @Override 2252d695813b44690ca146f95939acb00f0c14dac29John Spurlock public String toString() { 2262d695813b44690ca146f95939acb00f0c14dac29John Spurlock return String.format("PackageDrawableIcon[pkg=%s,id=0x%08x]", mPackage, mResId); 2272d695813b44690ca146f95939acb00f0c14dac29John Spurlock } 2282d695813b44690ca146f95939acb00f0c14dac29John Spurlock } 229bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock} 230