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;
33383db5ebcc3a4a615faf249bf4f126f42e80b82eTamas Berghammerimport com.android.internal.logging.nano.MetricsProto.MetricsEvent;
349c7844cb91b43929d0a86b1c90aa1efb37f5463aJason Monkimport com.android.systemui.Dependency;
35ec34da8f6f31c5ee1e543c0c7999a067487e0ce9Jason Monkimport com.android.systemui.plugins.ActivityStarter;
36702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monkimport com.android.systemui.qs.QSHost;
37702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monkimport com.android.systemui.plugins.qs.QSTile;
38702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monkimport com.android.systemui.plugins.qs.QSTile.State;
39702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monkimport com.android.systemui.qs.tileimpl.QSTileImpl;
40bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock
412d695813b44690ca146f95939acb00f0c14dac29John Spurlockimport java.util.Arrays;
422d695813b44690ca146f95939acb00f0c14dac29John Spurlockimport java.util.Objects;
432d695813b44690ca146f95939acb00f0c14dac29John Spurlock
44702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monkpublic class IntentTile extends QSTileImpl<State> {
45bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock    public static final String PREFIX = "intent(";
46bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock
47bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock    private PendingIntent mOnClick;
48bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock    private String mOnClickUri;
49c247b8f7270dd70ecc36977fcc0530217879f665John Spurlock    private PendingIntent mOnLongClick;
50c247b8f7270dd70ecc36977fcc0530217879f665John Spurlock    private String mOnLongClickUri;
51bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock    private int mCurrentUserId;
52457a21cdeac04565a0c40ad8c43a928c1182ddd1Chris Wren    private String mIntentPackage;
53bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock
54878c093336b324962f1b659aa29c79caed75ef2fJason Monk    private Intent mLastIntent;
55878c093336b324962f1b659aa29c79caed75ef2fJason Monk
56702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk    private IntentTile(QSHost host, String action) {
57bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock        super(host);
58bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock        mContext.registerReceiver(mReceiver, new IntentFilter(action));
59bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock    }
60bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock
61bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock    @Override
62bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock    protected void handleDestroy() {
63bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock        super.handleDestroy();
64bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock        mContext.unregisterReceiver(mReceiver);
65bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock    }
66bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock
67702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk    public static QSTile create(QSHost host, String spec) {
68bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock        if (spec == null || !spec.startsWith(PREFIX) || !spec.endsWith(")")) {
69bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock            throw new IllegalArgumentException("Bad intent tile spec: " + spec);
70bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock        }
71bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock        final String action = spec.substring(PREFIX.length(), spec.length() - 1);
72bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock        if (action.isEmpty()) {
73bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock            throw new IllegalArgumentException("Empty intent tile spec action");
74bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock        }
75bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock        return new IntentTile(host, action);
76bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock    }
77bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock
78bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock    @Override
79bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock    public void setListening(boolean listening) {
80bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock    }
81bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock
82bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock    @Override
8362b63a02d7ca630e3ad39991ea6550cab57e5d22Jason Monk    public State newTileState() {
84bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock        return new State();
85bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock    }
86bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock
87bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock    @Override
88bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock    protected void handleUserSwitch(int newUserId) {
89bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock        super.handleUserSwitch(newUserId);
90bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock        mCurrentUserId = newUserId;
91bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock    }
92bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock
93bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock    @Override
94bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock    protected void handleClick() {
95c247b8f7270dd70ecc36977fcc0530217879f665John Spurlock        sendIntent("click", mOnClick, mOnClickUri);
96c247b8f7270dd70ecc36977fcc0530217879f665John Spurlock    }
97c247b8f7270dd70ecc36977fcc0530217879f665John Spurlock
98c247b8f7270dd70ecc36977fcc0530217879f665John Spurlock    @Override
9976c67aa361f65dfb2f5e03d06cc1ccebce9cecd9Jason Monk    public Intent getLongClickIntent() {
10076c67aa361f65dfb2f5e03d06cc1ccebce9cecd9Jason Monk        return null;
10176c67aa361f65dfb2f5e03d06cc1ccebce9cecd9Jason Monk    }
10276c67aa361f65dfb2f5e03d06cc1ccebce9cecd9Jason Monk
10376c67aa361f65dfb2f5e03d06cc1ccebce9cecd9Jason Monk    @Override
104c247b8f7270dd70ecc36977fcc0530217879f665John Spurlock    protected void handleLongClick() {
105c247b8f7270dd70ecc36977fcc0530217879f665John Spurlock        sendIntent("long-click", mOnLongClick, mOnLongClickUri);
106c247b8f7270dd70ecc36977fcc0530217879f665John Spurlock    }
107c247b8f7270dd70ecc36977fcc0530217879f665John Spurlock
108c247b8f7270dd70ecc36977fcc0530217879f665John Spurlock    private void sendIntent(String type, PendingIntent pi, String uri) {
109bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock        try {
110c247b8f7270dd70ecc36977fcc0530217879f665John Spurlock            if (pi != null) {
111ee43cdfa43b09a79e66d81f6673a79bc26427343Jason Monk                if (pi.isActivity()) {
1129c7844cb91b43929d0a86b1c90aa1efb37f5463aJason Monk                    Dependency.get(ActivityStarter.class).postStartActivityDismissingKeyguard(pi);
113ee43cdfa43b09a79e66d81f6673a79bc26427343Jason Monk                } else {
114ee43cdfa43b09a79e66d81f6673a79bc26427343Jason Monk                    pi.send();
115ee43cdfa43b09a79e66d81f6673a79bc26427343Jason Monk                }
116c247b8f7270dd70ecc36977fcc0530217879f665John Spurlock            } else if (uri != null) {
117c247b8f7270dd70ecc36977fcc0530217879f665John Spurlock                final Intent intent = Intent.parseUri(uri, Intent.URI_INTENT_SCHEME);
118bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock                mContext.sendBroadcastAsUser(intent, new UserHandle(mCurrentUserId));
119bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock            }
120bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock        } catch (Throwable t) {
121c247b8f7270dd70ecc36977fcc0530217879f665John Spurlock            Log.w(TAG, "Error sending " + type + " intent", t);
122bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock        }
123bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock    }
124bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock
125bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock    @Override
12639c98e652fd3e0e3ea3a334d60ba6ee979985978Jason Monk    public CharSequence getTileLabel() {
12739c98e652fd3e0e3ea3a334d60ba6ee979985978Jason Monk        return getState().label;
12839c98e652fd3e0e3ea3a334d60ba6ee979985978Jason Monk    }
12939c98e652fd3e0e3ea3a334d60ba6ee979985978Jason Monk
13039c98e652fd3e0e3ea3a334d60ba6ee979985978Jason Monk    @Override
131bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock    protected void handleUpdateState(State state, Object arg) {
132878c093336b324962f1b659aa29c79caed75ef2fJason Monk        Intent intent = (Intent) arg;
133878c093336b324962f1b659aa29c79caed75ef2fJason Monk        if (intent == null) {
134878c093336b324962f1b659aa29c79caed75ef2fJason Monk            if (mLastIntent == null) {
135878c093336b324962f1b659aa29c79caed75ef2fJason Monk                return;
136878c093336b324962f1b659aa29c79caed75ef2fJason Monk            }
137878c093336b324962f1b659aa29c79caed75ef2fJason Monk            // No intent but need to refresh state, just use the last one.
138878c093336b324962f1b659aa29c79caed75ef2fJason Monk            intent = mLastIntent;
139878c093336b324962f1b659aa29c79caed75ef2fJason Monk        }
140878c093336b324962f1b659aa29c79caed75ef2fJason Monk        // Save the last one in case we need it later.
141878c093336b324962f1b659aa29c79caed75ef2fJason Monk        mLastIntent = intent;
142bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock        state.contentDescription = intent.getStringExtra("contentDescription");
143bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock        state.label = intent.getStringExtra("label");
144bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock        state.icon = null;
145bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock        final byte[] iconBitmap = intent.getByteArrayExtra("iconBitmap");
146bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock        if (iconBitmap != null) {
147bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock            try {
1482d695813b44690ca146f95939acb00f0c14dac29John Spurlock                state.icon = new BytesIcon(iconBitmap);
149bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock            } catch (Throwable t) {
150bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock                Log.w(TAG, "Error loading icon bitmap, length " + iconBitmap.length, t);
151bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock            }
152bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock        } else {
153bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock            final int iconId = intent.getIntExtra("iconId", 0);
154bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock            if (iconId != 0) {
155bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock                final String iconPackage = intent.getStringExtra("iconPackage");
156bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock                if (!TextUtils.isEmpty(iconPackage)) {
1572d695813b44690ca146f95939acb00f0c14dac29John Spurlock                    state.icon = new PackageDrawableIcon(iconPackage, iconId);
158bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock                } else {
1592d695813b44690ca146f95939acb00f0c14dac29John Spurlock                    state.icon = ResourceIcon.get(iconId);
160bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock                }
161bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock            }
162bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock        }
163bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock        mOnClick = intent.getParcelableExtra("onClick");
164bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock        mOnClickUri = intent.getStringExtra("onClickUri");
165c247b8f7270dd70ecc36977fcc0530217879f665John Spurlock        mOnLongClick = intent.getParcelableExtra("onLongClick");
166c247b8f7270dd70ecc36977fcc0530217879f665John Spurlock        mOnLongClickUri = intent.getStringExtra("onLongClickUri");
167457a21cdeac04565a0c40ad8c43a928c1182ddd1Chris Wren        mIntentPackage = intent.getStringExtra("package");
1689e7283f6a31bc2beb75c84c6173968a46582c563Chris Wren        mIntentPackage = mIntentPackage == null ? "" : mIntentPackage;
169457a21cdeac04565a0c40ad8c43a928c1182ddd1Chris Wren    }
170457a21cdeac04565a0c40ad8c43a928c1182ddd1Chris Wren
171457a21cdeac04565a0c40ad8c43a928c1182ddd1Chris Wren    @Override
172457a21cdeac04565a0c40ad8c43a928c1182ddd1Chris Wren    public int getMetricsCategory() {
173f6e9228b8a97603d3ceb8f0d61e8d87cf19bd21fChris Wren        return MetricsEvent.QS_INTENT;
174457a21cdeac04565a0c40ad8c43a928c1182ddd1Chris Wren    }
175457a21cdeac04565a0c40ad8c43a928c1182ddd1Chris Wren
176bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
177bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock        @Override
178bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock        public void onReceive(Context context, Intent intent) {
179bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock            refreshState(intent);
180bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock        }
181bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock    };
1822d695813b44690ca146f95939acb00f0c14dac29John Spurlock
1832d695813b44690ca146f95939acb00f0c14dac29John Spurlock    private static class BytesIcon extends Icon {
1842d695813b44690ca146f95939acb00f0c14dac29John Spurlock        private final byte[] mBytes;
1852d695813b44690ca146f95939acb00f0c14dac29John Spurlock
1862d695813b44690ca146f95939acb00f0c14dac29John Spurlock        public BytesIcon(byte[] bytes) {
1872d695813b44690ca146f95939acb00f0c14dac29John Spurlock            mBytes = bytes;
1882d695813b44690ca146f95939acb00f0c14dac29John Spurlock        }
1892d695813b44690ca146f95939acb00f0c14dac29John Spurlock
1902d695813b44690ca146f95939acb00f0c14dac29John Spurlock        @Override
1912d695813b44690ca146f95939acb00f0c14dac29John Spurlock        public Drawable getDrawable(Context context) {
1922d695813b44690ca146f95939acb00f0c14dac29John Spurlock            final Bitmap b = BitmapFactory.decodeByteArray(mBytes, 0, mBytes.length);
1932d695813b44690ca146f95939acb00f0c14dac29John Spurlock            return new BitmapDrawable(context.getResources(), b);
1942d695813b44690ca146f95939acb00f0c14dac29John Spurlock        }
1952d695813b44690ca146f95939acb00f0c14dac29John Spurlock
1962d695813b44690ca146f95939acb00f0c14dac29John Spurlock        @Override
1972d695813b44690ca146f95939acb00f0c14dac29John Spurlock        public boolean equals(Object o) {
1982d695813b44690ca146f95939acb00f0c14dac29John Spurlock            return o instanceof BytesIcon && Arrays.equals(((BytesIcon) o).mBytes, mBytes);
1992d695813b44690ca146f95939acb00f0c14dac29John Spurlock        }
2002d695813b44690ca146f95939acb00f0c14dac29John Spurlock
2012d695813b44690ca146f95939acb00f0c14dac29John Spurlock        @Override
2022d695813b44690ca146f95939acb00f0c14dac29John Spurlock        public String toString() {
2032d695813b44690ca146f95939acb00f0c14dac29John Spurlock            return String.format("BytesIcon[len=%s]", mBytes.length);
2042d695813b44690ca146f95939acb00f0c14dac29John Spurlock        }
2052d695813b44690ca146f95939acb00f0c14dac29John Spurlock    }
2062d695813b44690ca146f95939acb00f0c14dac29John Spurlock
2072d695813b44690ca146f95939acb00f0c14dac29John Spurlock    private class PackageDrawableIcon extends Icon {
2082d695813b44690ca146f95939acb00f0c14dac29John Spurlock        private final String mPackage;
2092d695813b44690ca146f95939acb00f0c14dac29John Spurlock        private final int mResId;
2102d695813b44690ca146f95939acb00f0c14dac29John Spurlock
2112d695813b44690ca146f95939acb00f0c14dac29John Spurlock        public PackageDrawableIcon(String pkg, int resId) {
2122d695813b44690ca146f95939acb00f0c14dac29John Spurlock            mPackage = pkg;
2132d695813b44690ca146f95939acb00f0c14dac29John Spurlock            mResId = resId;
2142d695813b44690ca146f95939acb00f0c14dac29John Spurlock        }
2152d695813b44690ca146f95939acb00f0c14dac29John Spurlock
2162d695813b44690ca146f95939acb00f0c14dac29John Spurlock        @Override
2172d695813b44690ca146f95939acb00f0c14dac29John Spurlock        public boolean equals(Object o) {
2182d695813b44690ca146f95939acb00f0c14dac29John Spurlock            if (!(o instanceof PackageDrawableIcon)) return false;
2192d695813b44690ca146f95939acb00f0c14dac29John Spurlock            final PackageDrawableIcon other = (PackageDrawableIcon) o;
2202d695813b44690ca146f95939acb00f0c14dac29John Spurlock            return Objects.equals(other.mPackage, mPackage) && other.mResId == mResId;
2212d695813b44690ca146f95939acb00f0c14dac29John Spurlock        }
2222d695813b44690ca146f95939acb00f0c14dac29John Spurlock
2232d695813b44690ca146f95939acb00f0c14dac29John Spurlock        @Override
2242d695813b44690ca146f95939acb00f0c14dac29John Spurlock        public Drawable getDrawable(Context context) {
2252d695813b44690ca146f95939acb00f0c14dac29John Spurlock            try {
2262d695813b44690ca146f95939acb00f0c14dac29John Spurlock                return context.createPackageContext(mPackage, 0).getDrawable(mResId);
2272d695813b44690ca146f95939acb00f0c14dac29John Spurlock            } catch (Throwable t) {
2282d695813b44690ca146f95939acb00f0c14dac29John Spurlock                Log.w(TAG, "Error loading package drawable pkg=" + mPackage + " id=" + mResId, t);
2292d695813b44690ca146f95939acb00f0c14dac29John Spurlock                return null;
2302d695813b44690ca146f95939acb00f0c14dac29John Spurlock            }
2312d695813b44690ca146f95939acb00f0c14dac29John Spurlock        }
2322d695813b44690ca146f95939acb00f0c14dac29John Spurlock
2332d695813b44690ca146f95939acb00f0c14dac29John Spurlock        @Override
2342d695813b44690ca146f95939acb00f0c14dac29John Spurlock        public String toString() {
2352d695813b44690ca146f95939acb00f0c14dac29John Spurlock            return String.format("PackageDrawableIcon[pkg=%s,id=0x%08x]", mPackage, mResId);
2362d695813b44690ca146f95939acb00f0c14dac29John Spurlock        }
2372d695813b44690ca146f95939acb00f0c14dac29John Spurlock    }
238bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock}
239