diff --git a/car-apps-common/src/com/android/car/apps/common/AccountImageChangeObserver.java b/car-apps-common/src/com/android/car/apps/common/AccountImageChangeObserver.java
deleted file mode 100644
index cbfe5a4..0000000
--- a/car-apps-common/src/com/android/car/apps/common/AccountImageChangeObserver.java
+++ /dev/null
@@ -1,193 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.car.apps.common;
-
-import static android.Manifest.permission.GET_ACCOUNTS;
-
-import android.accounts.Account;
-import android.accounts.AccountManager;
-import android.annotation.RequiresPermission;
-import android.content.ContentUris;
-import android.content.Context;
-import android.database.ContentObserver;
-import android.database.Cursor;
-import android.net.Uri;
-import android.provider.ContactsContract;
-import android.provider.ContactsContract.Contacts;
-import android.text.TextUtils;
-
-import java.util.HashMap;
-import java.util.LinkedHashSet;
-
-/**
- * @hide
- */
-public class AccountImageChangeObserver {
-    private static final String GOOGLE_ACCOUNT_TYPE = "com.google";
-
-    private static final Object sObserverInstanceLock = new Object();
-    private static AccountImageChangeObserver sObserver;
-
-    private class ContactChangeContentObserver extends ContentObserver {
-        private final Account mWatchedAccount;
-        private final LinkedHashSet<Uri> mUrisToNotify;
-        private final Object mLock = new Object();
-        private final Context mContext;
-        private String mCurrentImageUri;
-
-        public ContactChangeContentObserver(Context context, Account watchedAccount) {
-            super(null);
-            mWatchedAccount = watchedAccount;
-            mUrisToNotify = new LinkedHashSet<>();
-            mContext = context;
-            mCurrentImageUri = AccountImageHelper.getAccountPictureUri(mContext, mWatchedAccount);
-        }
-
-        @Override
-        public boolean deliverSelfNotifications() {
-            return true;
-        }
-
-        public void addUriToNotifyList(Uri uri) {
-            synchronized (mLock) {
-                mUrisToNotify.add(uri);
-            }
-        }
-
-        @Override
-        public void onChange(boolean selfChange) {
-            String newUri = AccountImageHelper.getAccountPictureUri(mContext, mWatchedAccount);
-
-            if (TextUtils.equals(mCurrentImageUri, newUri)) {
-                // no change, no need to notify
-                return;
-            }
-
-            synchronized (mLock) {
-                for (Uri uri : mUrisToNotify) {
-                    mContext.getContentResolver().notifyChange(uri, null);
-                }
-
-                mCurrentImageUri = newUri;
-            }
-        }
-    }
-
-    private final HashMap<String, ContactChangeContentObserver> mObserverMap;
-
-
-    /**
-     * get the singleton AccountImageChangeObserver for the application
-     */
-    public final static AccountImageChangeObserver getInstance() {
-        if (sObserver == null) {
-            synchronized (sObserverInstanceLock) {
-                if (sObserver == null) {
-                    sObserver = new AccountImageChangeObserver();
-                }
-            }
-        }
-        return sObserver;
-    }
-
-    public AccountImageChangeObserver() {
-        mObserverMap = new HashMap<>();
-    }
-
-    @RequiresPermission(GET_ACCOUNTS)
-    public synchronized void registerChangeUriIfPresent(BitmapWorkerOptions options) {
-        Uri imageUri = options.getResourceUri();
-        // Only register URIs that match the Account Image URI schema, and
-        // have a change notify URI specified.
-        if (imageUri != null && UriUtils.isAccountImageUri(imageUri)) {
-            Uri changeNotifUri = UriUtils.getAccountImageChangeNotifyUri(imageUri);
-            imageUri = imageUri.buildUpon().clearQuery().build();
-
-            if (changeNotifUri == null) {
-                // No change Notiy URI specified
-                return;
-            }
-
-            String accountName = UriUtils.getAccountName(imageUri);
-            Context context = options.getContext();
-
-            if (accountName != null && context != null) {
-                Account thisAccount = null;
-                for (Account account : AccountManager.get(context).
-                        getAccountsByType(GOOGLE_ACCOUNT_TYPE)) {
-                    if (account.name.equals(accountName)) {
-                        thisAccount = account;
-                        break;
-                    }
-                }
-                if (thisAccount != null) {
-                    ContactChangeContentObserver observer;
-
-                    if (mObserverMap.containsKey(thisAccount.name)) {
-                        observer = mObserverMap.get(thisAccount.name);
-                        if (observer != null) {
-                            observer.addUriToNotifyList(changeNotifUri);
-                        }
-                    } else {
-                        long contactId = getContactIdForAccount(context, thisAccount);
-                        if (contactId != -1) {
-                            Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI,
-                                    contactId);
-                            observer = new ContactChangeContentObserver(context, thisAccount);
-                            mObserverMap.put(thisAccount.name, observer);
-                            observer.addUriToNotifyList(changeNotifUri);
-                            context.getContentResolver().registerContentObserver(contactUri, false,
-                                    observer);
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-    private long getContactIdForAccount(Context context, Account account) {
-        // Look up this account in the contacts database.
-        String[] projection = new String[] {
-                ContactsContract.Data._ID,
-                ContactsContract.Data.CONTACT_ID,
-                ContactsContract.Data.LOOKUP_KEY
-        };
-        String selection =
-                ContactsContract.CommonDataKinds.Email.ADDRESS + " LIKE ?";
-        String[] selectionArgs = new String[] { account.name };
-        Cursor c = null;
-        long contactId = -1;
-        String lookupKey = null;
-        try {
-            c = context.getContentResolver().query(ContactsContract.Data.CONTENT_URI,
-                    projection, selection, selectionArgs, null);
-            if (c.moveToNext()) {
-                contactId = c.getLong(1);
-                lookupKey = c.getString(2);
-            }
-        } finally {
-            if (c != null) {
-                c.close();
-            }
-        }
-
-        if (contactId != -1 && !TextUtils.isEmpty(lookupKey)) {
-            return contactId;
-        }
-
-        return -1;
-    }
-}
diff --git a/car-apps-common/src/com/android/car/apps/common/BitmapDownloader.java b/car-apps-common/src/com/android/car/apps/common/BitmapDownloader.java
deleted file mode 100644
index 9600585..0000000
--- a/car-apps-common/src/com/android/car/apps/common/BitmapDownloader.java
+++ /dev/null
@@ -1,338 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.car.apps.common;
-
-import android.app.ActivityManager;
-import android.content.Context;
-import android.graphics.Bitmap;
-import android.util.Log;
-import android.util.LruCache;
-import android.widget.ImageView;
-
-import java.lang.ref.SoftReference;
-import java.util.concurrent.Executor;
-import java.util.concurrent.Executors;
-
-/**
- * Downloader class which loads a resource URI into an image view.
- * <p>
- * This class adds a cache over BitmapWorkerTask.
- */
-public class BitmapDownloader {
-
-    private static final String TAG = "BitmapDownloader";
-
-    private static final boolean DEBUG = false;
-
-    private static final int CORE_POOL_SIZE = 5;
-
-    private static final Executor BITMAP_DOWNLOADER_THREAD_POOL_EXECUTOR =
-            Executors.newFixedThreadPool(CORE_POOL_SIZE);
-
-    // 1/4 of max memory is used for bitmap mem cache
-    private static final int MEM_TO_CACHE = 4;
-
-    // hard limit for bitmap mem cache in MB
-    private static final int CACHE_HARD_LIMIT = 32;
-
-    /**
-     * bitmap cache item structure saved in LruCache
-     */
-    private static class BitmapItem {
-        /**
-         * cached bitmap
-         */
-        Bitmap mBitmap;
-        /**
-         * indicate if the bitmap is scaled down from original source (never scale up)
-         */
-        boolean mScaled;
-
-        public BitmapItem(Bitmap bitmap, boolean scaled) {
-            mBitmap = bitmap;
-            mScaled = scaled;
-        }
-    }
-
-    private LruCache<String, BitmapItem> mMemoryCache;
-
-    private static BitmapDownloader sBitmapDownloader;
-
-    private static final Object sBitmapDownloaderLock = new Object();
-
-    // Bitmap cache also uses size of Bitmap as part of key.
-    // Bitmap cache is divided into following buckets by height:
-    // TODO: Pano currently is caring more about height, what about width in key?
-    // height <= 128, 128 < height <= 512, height > 512
-    // Different bitmap cache buckets save different bitmap cache items.
-    // Bitmaps within same bucket share the largest cache item.
-    private static final int[] SIZE_BUCKET = new int[]{128, 512, Integer.MAX_VALUE};
-
-    public static abstract class BitmapCallback {
-        SoftReference<BitmapWorkerTask> mTask;
-
-        public abstract void onBitmapRetrieved(Bitmap bitmap);
-    }
-
-    /**
-     * get the singleton BitmapDownloader for the application
-     */
-    public final static BitmapDownloader getInstance(Context context) {
-        if (sBitmapDownloader == null) {
-            synchronized(sBitmapDownloaderLock) {
-                if (sBitmapDownloader == null) {
-                    sBitmapDownloader = new BitmapDownloader(context);
-                }
-            }
-        }
-        return sBitmapDownloader;
-    }
-
-    public BitmapDownloader(Context context) {
-        int memClass = ((ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE))
-                .getMemoryClass();
-        memClass = memClass / MEM_TO_CACHE;
-        if (memClass > CACHE_HARD_LIMIT) {
-            memClass = CACHE_HARD_LIMIT;
-        }
-        int cacheSize = 1024 * 1024 * memClass;
-        mMemoryCache = new LruCache<String, BitmapItem>(cacheSize) {
-            @Override
-            protected int sizeOf(String key, BitmapItem bitmap) {
-                return bitmap.mBitmap.getByteCount();
-            }
-        };
-    }
-
-    /**
-     * load bitmap in current thread, will *block* current thread.
-     * @deprecated
-     */
-    @Deprecated
-    public final Bitmap loadBitmapBlocking(final BitmapWorkerOptions options) {
-        final boolean hasAccountImageUri = UriUtils.isAccountImageUri(options.getResourceUri());
-        Bitmap bitmap = null;
-        if (hasAccountImageUri) {
-            AccountImageChangeObserver.getInstance().registerChangeUriIfPresent(options);
-        } else {
-            bitmap = getBitmapFromMemCache(options);
-        }
-
-        if (bitmap == null) {
-            BitmapWorkerTask task = new BitmapWorkerTask(null) {
-                @Override
-                protected Bitmap doInBackground(BitmapWorkerOptions... params) {
-                    final Bitmap bitmap = super.doInBackground(params);
-                    if (bitmap != null && !hasAccountImageUri) {
-                        addBitmapToMemoryCache(params[0], bitmap, isScaled());
-                    }
-                    return bitmap;
-                }
-            };
-
-            return task.doInBackground(options);
-        }
-        return bitmap;
-    }
-
-    /**
-     * Loads the bitmap into the image view.
-     */
-    public void loadBitmap(final BitmapWorkerOptions options, final ImageView imageView) {
-        cancelDownload(imageView);
-        final boolean hasAccountImageUri = UriUtils.isAccountImageUri(options.getResourceUri());
-        Bitmap bitmap = null;
-        if (hasAccountImageUri) {
-            AccountImageChangeObserver.getInstance().registerChangeUriIfPresent(options);
-        } else {
-            bitmap = getBitmapFromMemCache(options);
-        }
-
-        if (bitmap != null) {
-            imageView.setImageBitmap(bitmap);
-        } else {
-            BitmapWorkerTask task = new BitmapWorkerTask(imageView) {
-                @Override
-                protected Bitmap doInBackground(BitmapWorkerOptions... params) {
-                    Bitmap bitmap = super.doInBackground(params);
-                    if (bitmap != null && !hasAccountImageUri) {
-                        addBitmapToMemoryCache(params[0], bitmap, isScaled());
-                    }
-                    return bitmap;
-                }
-            };
-            imageView.setTag(R.id.imageDownloadTask, new SoftReference<BitmapWorkerTask>(task));
-            task.execute(options);
-        }
-    }
-
-    /**
-     * Loads the bitmap.
-     * <p>
-     * This will be sent back to the callback object.
-     */
-    public void getBitmap(final BitmapWorkerOptions options, final BitmapCallback callback) {
-        cancelDownload(callback);
-        final boolean hasAccountImageUri = UriUtils.isAccountImageUri(options.getResourceUri());
-        final Bitmap bitmap = hasAccountImageUri ? null : getBitmapFromMemCache(options);
-        if (hasAccountImageUri) {
-            AccountImageChangeObserver.getInstance().registerChangeUriIfPresent(options);
-        }
-
-        BitmapWorkerTask task = new BitmapWorkerTask(null) {
-            @Override
-            protected Bitmap doInBackground(BitmapWorkerOptions... params) {
-                if (bitmap != null) {
-                    return bitmap;
-                }
-                final Bitmap bitmap = super.doInBackground(params);
-                if (bitmap != null && !hasAccountImageUri) {
-                    addBitmapToMemoryCache(params[0], bitmap, isScaled());
-                }
-                return bitmap;
-            }
-
-            @Override
-            protected void onPostExecute(Bitmap bitmap) {
-                callback.onBitmapRetrieved(bitmap);
-            }
-        };
-        callback.mTask = new SoftReference<BitmapWorkerTask>(task);
-        task.executeOnExecutor(BITMAP_DOWNLOADER_THREAD_POOL_EXECUTOR, options);
-    }
-
-    /**
-     * Cancel download<p>
-     * @param key {@link BitmapCallback} or {@link ImageView}
-     */
-    @SuppressWarnings("unchecked")
-    public boolean cancelDownload(Object key) {
-        BitmapWorkerTask task = null;
-        if (key instanceof ImageView) {
-            ImageView imageView = (ImageView)key;
-            SoftReference<BitmapWorkerTask> softReference =
-                    (SoftReference<BitmapWorkerTask>) imageView.getTag(R.id.imageDownloadTask);
-            if (softReference != null) {
-                task = softReference.get();
-                softReference.clear();
-            }
-        } else if (key instanceof BitmapCallback) {
-            BitmapCallback callback = (BitmapCallback) key;
-            if (callback.mTask != null) {
-                task = callback.mTask.get();
-                callback.mTask = null;
-            }
-        }
-        if (task != null) {
-            return task.cancel(true);
-        }
-        return false;
-    }
-
-    private static String getBucketKey(String baseKey, Bitmap.Config bitmapConfig, int width) {
-        for (int i = 0; i < SIZE_BUCKET.length; i++) {
-            if (width <= SIZE_BUCKET[i]) {
-                return new StringBuilder(baseKey.length() + 16).append(baseKey)
-                        .append(":").append(bitmapConfig == null ? "" : bitmapConfig.ordinal())
-                        .append(":").append(SIZE_BUCKET[i]).toString();
-            }
-        }
-        // should never happen because last bucket is Integer.MAX_VALUE
-        throw new RuntimeException();
-    }
-
-    private void addBitmapToMemoryCache(BitmapWorkerOptions key, Bitmap bitmap, boolean isScaled) {
-        if (!key.isMemCacheEnabled()) {
-            return;
-        }
-        String bucketKey = getBucketKey(
-                key.getCacheKey(), key.getBitmapConfig(), bitmap.getHeight());
-        BitmapItem bitmapItem = mMemoryCache.get(bucketKey);
-        if (bitmapItem != null) {
-            Bitmap currentBitmap = bitmapItem.mBitmap;
-            // If somebody else happened to get a larger one in the bucket, discard our bitmap.
-            // TODO: need a better way to prevent current downloading for the same Bitmap
-            if (currentBitmap.getWidth() >= bitmap.getWidth() && currentBitmap.getHeight()
-                    >= bitmap.getHeight()) {
-                return;
-            }
-        }
-        if (DEBUG) {
-            Log.d(TAG, "add cache "+bucketKey+" isScaled = "+isScaled);
-        }
-        bitmapItem = new BitmapItem(bitmap, isScaled);
-        mMemoryCache.put(bucketKey, bitmapItem);
-    }
-
-    private Bitmap getBitmapFromMemCache(BitmapWorkerOptions key) {
-        if (key.getHeight() != BitmapWorkerOptions.MAX_IMAGE_DIMENSION_PX) {
-            // 1. find the bitmap in the size bucket
-            String bucketKey =
-                    getBucketKey(key.getCacheKey(), key.getBitmapConfig(), key.getHeight());
-            BitmapItem bitmapItem = mMemoryCache.get(bucketKey);
-            if (bitmapItem != null) {
-                Bitmap bitmap = bitmapItem.mBitmap;
-                // now we have the bitmap in the bucket, use it when the bitmap is not scaled or
-                // if the size is larger than or equals to the output size
-                if (!bitmapItem.mScaled) {
-                    return bitmap;
-                }
-                if (bitmap.getHeight() >= key.getHeight()) {
-                    return bitmap;
-                }
-            }
-            // 2. find un-scaled bitmap in smaller buckets.  If the un-scaled bitmap exists
-            // in higher buckets,  we still need to scale it down.  Right now we just
-            // return null and let the BitmapWorkerTask to do the same job again.
-            // TODO: use the existing unscaled bitmap and we don't need to load it from resource
-            // or network again.
-            for (int i = SIZE_BUCKET.length - 1; i >= 0; i--) {
-                if (SIZE_BUCKET[i] >= key.getHeight()) {
-                    continue;
-                }
-                bucketKey = getBucketKey(key.getCacheKey(), key.getBitmapConfig(), SIZE_BUCKET[i]);
-                bitmapItem = mMemoryCache.get(bucketKey);
-                if (bitmapItem != null && !bitmapItem.mScaled) {
-                    return bitmapItem.mBitmap;
-                }
-            }
-            return null;
-        }
-        // 3. find un-scaled bitmap if size is not specified
-        for (int i = SIZE_BUCKET.length - 1; i >= 0; i--) {
-            String bucketKey =
-                    getBucketKey(key.getCacheKey(), key.getBitmapConfig(), SIZE_BUCKET[i]);
-            BitmapItem bitmapItem = mMemoryCache.get(bucketKey);
-            if (bitmapItem != null && !bitmapItem.mScaled) {
-                return bitmapItem.mBitmap;
-            }
-        }
-        return null;
-    }
-
-    public Bitmap getLargestBitmapFromMemCache(BitmapWorkerOptions key) {
-        // find largest bitmap matching the key
-        for (int i = SIZE_BUCKET.length - 1; i >= 0; i--) {
-            String bucketKey =
-                    getBucketKey(key.getCacheKey(), key.getBitmapConfig(), SIZE_BUCKET[i]);
-            BitmapItem bitmapItem = mMemoryCache.get(bucketKey);
-            if (bitmapItem != null) {
-                return bitmapItem.mBitmap;
-            }
-        }
-        return null;
-    }
-}
diff --git a/car-apps-common/src/com/android/car/apps/common/BitmapWorkerOptions.java b/car-apps-common/src/com/android/car/apps/common/BitmapWorkerOptions.java
deleted file mode 100644
index 5f22e79..0000000
--- a/car-apps-common/src/com/android/car/apps/common/BitmapWorkerOptions.java
+++ /dev/null
@@ -1,222 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.car.apps.common;
-
-import android.content.Context;
-import android.content.Intent.ShortcutIconResource;
-import android.graphics.Bitmap;
-import android.net.Uri;
-import android.text.TextUtils;
-
-/**
- * Options for loading bitmap resources from different sources and for scaling to an appropriate
- * resolution.
- */
-public class BitmapWorkerOptions {
-
-    /** Max image size handled by android.graphics */
-    static final int MAX_IMAGE_DIMENSION_PX = 2048;
-
-    /** flag to force disable memory cache */
-    public static final int CACHE_FLAG_MEM_DISABLED = 1;
-    /** TODO support disk cache options */
-    public static final int CACHE_FLAG_DISK_DISABLED = 2;
-
-    private ShortcutIconResource mIconResource;
-    private Uri mResourceUri;
-
-    private int mWidth;
-    private int mHeight;
-    private Context mContext;
-    private int mCacheFlag;
-    private Bitmap.Config mBitmapConfig;
-
-    private String mKey;
-
-    /**
-     * Builds options for a bitmap worker task.
-     */
-    public static class Builder {
-
-        private String mPackageName;
-        private String mResourceName;
-        private Uri mResourceUri;
-
-        private int mWidth;
-        private int mHeight;
-        private Context mContext;
-        private int mCacheFlag;
-        private Bitmap.Config mBitmapConfig;
-
-        public Builder(Context context) {
-            mWidth = MAX_IMAGE_DIMENSION_PX;
-            mHeight = MAX_IMAGE_DIMENSION_PX;
-            mContext = context;
-            mCacheFlag = 0;
-            mBitmapConfig = null;
-        }
-
-        public BitmapWorkerOptions build() {
-            BitmapWorkerOptions options = new BitmapWorkerOptions();
-
-            if (!TextUtils.isEmpty(mPackageName)) {
-                options.mIconResource = new ShortcutIconResource();
-                options.mIconResource.packageName = mPackageName;
-                options.mIconResource.resourceName = mResourceName;
-            }
-
-            final int largestDim = Math.max(mWidth, mHeight);
-            if (largestDim > MAX_IMAGE_DIMENSION_PX) {
-                double scale = (double) MAX_IMAGE_DIMENSION_PX / largestDim;
-                mWidth *= scale;
-                mHeight *= scale;
-            }
-
-            options.mResourceUri = mResourceUri;
-            options.mWidth = mWidth;
-            options.mHeight = mHeight;
-            options.mContext = mContext;
-            options.mCacheFlag = mCacheFlag;
-            options.mBitmapConfig = mBitmapConfig;
-            if (options.mIconResource == null && options.mResourceUri == null) {
-                throw new RuntimeException("Both Icon and ResourceUri are null");
-            }
-            return options;
-        }
-
-        public Builder resource(String packageName, String resourceName) {
-            mPackageName = packageName;
-            mResourceName = resourceName;
-            return this;
-        }
-
-        public Builder resource(ShortcutIconResource iconResource) {
-            mPackageName = iconResource.packageName;
-            mResourceName = iconResource.resourceName;
-            return this;
-        }
-
-        public Builder resource(Uri resourceUri) {
-            mResourceUri = resourceUri;
-            return this;
-        }
-
-        public Builder width(int width) {
-            if (width > 0) {
-                mWidth = width;
-            } else {
-                throw new IllegalArgumentException("Can't set width to " + width);
-            }
-            return this;
-        }
-
-        public Builder height(int height) {
-            if (height > 0) {
-                mHeight = height;
-            } else {
-                throw new IllegalArgumentException("Can't set height to " + height);
-            }
-            return this;
-        }
-
-        public Builder cacheFlag(int flag) {
-            mCacheFlag = flag;
-            return this;
-        }
-
-        public Builder bitmapConfig(Bitmap.Config config) {
-            mBitmapConfig = config;
-            return this;
-        }
-
-    }
-
-    /**
-     * Private constructor.
-     * <p>
-     * Use a {@link Builder} to create.
-     */
-    private BitmapWorkerOptions() {
-    }
-
-    public ShortcutIconResource getIconResource() {
-        return mIconResource;
-    }
-
-    public Uri getResourceUri() {
-        return mResourceUri;
-    }
-
-    public int getWidth() {
-        return mWidth;
-    }
-
-    public int getHeight() {
-        return mHeight;
-    }
-
-    public Context getContext() {
-        return mContext;
-    }
-
-    public boolean isFromResource() {
-        return getIconResource() != null ||
-                UriUtils.isAndroidResourceUri(getResourceUri())
-                || UriUtils.isShortcutIconResourceUri(getResourceUri());
-    }
-
-    /**
-     * Combination of CACHE_FLAG_MEM_DISABLED and CACHE_FLAG_DISK_DISABLED,
-     * 0 for fully cache enabled
-     */
-    public int getCacheFlag() {
-        return mCacheFlag;
-    }
-
-    public boolean isMemCacheEnabled() {
-        return (mCacheFlag & CACHE_FLAG_MEM_DISABLED) == 0;
-    }
-
-    public boolean isDiskCacheEnabled() {
-        return (mCacheFlag & CACHE_FLAG_DISK_DISABLED) == 0;
-    }
-
-    /**
-     * @return  preferred Bitmap config to decode bitmap, null for auto detect.
-     * Use {@link Builder#bitmapConfig(Bitmap.Config)} to change it.
-     */
-    public Bitmap.Config getBitmapConfig() {
-        return mBitmapConfig;
-    }
-
-    public String getCacheKey() {
-        if (mKey == null) {
-            mKey = mIconResource != null ? mIconResource.packageName + "/"
-                    + mIconResource.resourceName : mResourceUri.toString();
-        }
-        return mKey;
-    }
-
-    @Override
-    public String toString() {
-        if (mIconResource == null) {
-            return "URI: " + mResourceUri;
-        } else {
-            return "PackageName: " + mIconResource.packageName + " Resource: " + mIconResource
-                    + " URI: " + mResourceUri;
-        }
-    }
-}
diff --git a/car-apps-common/src/com/android/car/apps/common/BitmapWorkerTask.java b/car-apps-common/src/com/android/car/apps/common/BitmapWorkerTask.java
deleted file mode 100644
index aa8d67f..0000000
--- a/car-apps-common/src/com/android/car/apps/common/BitmapWorkerTask.java
+++ /dev/null
@@ -1,349 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.car.apps.common;
-
-import android.accounts.Account;
-import android.accounts.AccountManager;
-import android.content.Context;
-import android.content.Intent.ShortcutIconResource;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.content.res.Resources;
-import android.content.res.Resources.NotFoundException;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.graphics.Canvas;
-import android.graphics.drawable.Drawable;
-import android.net.Uri;
-import android.os.AsyncTask;
-import android.util.Log;
-import android.util.TypedValue;
-import android.widget.ImageView;
-
-import java.io.BufferedInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.lang.ref.WeakReference;
-import java.net.HttpURLConnection;
-import java.net.URL;
-
-/**
- * AsyncTask which loads a bitmap.
- * <p>
- * The source of this can be another package (via a resource), a URI (content provider), or
- * a file path.
- *
- * @see BitmapWorkerOptions
- * @hide
- */
-public class BitmapWorkerTask extends AsyncTask<BitmapWorkerOptions, Void, Bitmap> {
-
-    private static final String TAG = "BitmapWorker";
-    private static final String GOOGLE_ACCOUNT_TYPE = "com.google";
-
-    private static final boolean DEBUG = false;
-
-    private static final int SOCKET_TIMEOUT = 10000;
-    private static final int READ_TIMEOUT = 10000;
-
-    private final WeakReference<ImageView> mImageView;
-    // a flag for if the bitmap is scaled from original source
-    protected boolean mScaled;
-
-    public BitmapWorkerTask(ImageView imageView) {
-        mImageView = new WeakReference<ImageView>(imageView);
-        mScaled = false;
-    }
-
-    @Override
-    protected Bitmap doInBackground(BitmapWorkerOptions... params) {
-
-        return retrieveBitmap(params[0]);
-    }
-
-    protected Bitmap retrieveBitmap(BitmapWorkerOptions workerOptions) {
-        try {
-            if (workerOptions.getIconResource() != null) {
-                return getBitmapFromResource(workerOptions.getContext(),
-                        workerOptions.getIconResource(),
-                        workerOptions);
-            } else if (workerOptions.getResourceUri() != null) {
-                if (UriUtils.isAndroidResourceUri(workerOptions.getResourceUri())
-                        || UriUtils.isShortcutIconResourceUri(workerOptions.getResourceUri())) {
-                    // Make an icon resource from this.
-                    return getBitmapFromResource(workerOptions.getContext(),
-                            UriUtils.getIconResource(workerOptions.getResourceUri()),
-                            workerOptions);
-                } else if (UriUtils.isWebUri(workerOptions.getResourceUri())) {
-                        return getBitmapFromHttp(workerOptions);
-                } else if (UriUtils.isContentUri(workerOptions.getResourceUri())) {
-                    return getBitmapFromContent(workerOptions);
-                } else if (UriUtils.isAccountImageUri(workerOptions.getResourceUri())) {
-                    return getAccountImage(workerOptions);
-                } else {
-                    Log.e(TAG, "Error loading bitmap - unknown resource URI! "
-                            + workerOptions.getResourceUri());
-                }
-            } else {
-                Log.e(TAG, "Error loading bitmap - no source!");
-            }
-        } catch (IOException e) {
-            Log.e(TAG, "Error loading url " + workerOptions.getResourceUri(), e);
-            return null;
-        } catch (RuntimeException e) {
-            Log.e(TAG, "Critical Error loading url " + workerOptions.getResourceUri(), e);
-            return null;
-        }
-
-        return null;
-    }
-
-    @Override
-    protected void onPostExecute(Bitmap bitmap) {
-        if (mImageView != null) {
-            final ImageView imageView = mImageView.get();
-            if (imageView != null) {
-                imageView.setImageBitmap(bitmap);
-            }
-        }
-    }
-
-    private Bitmap getBitmapFromResource(Context context, ShortcutIconResource iconResource,
-            BitmapWorkerOptions outputOptions) throws IOException {
-        if (DEBUG) {
-            Log.d(TAG, "Loading " + iconResource.toString());
-        }
-        try {
-            Object drawable = loadDrawable(context, iconResource);
-            if (drawable instanceof InputStream) {
-                // Most of these are bitmaps, so resize properly.
-                return decodeBitmap((InputStream) drawable, outputOptions);
-            } else if (drawable instanceof Drawable){
-                return createIconBitmap((Drawable) drawable, outputOptions);
-            } else {
-                Log.w(TAG, "getBitmapFromResource failed, unrecognized resource: " + drawable);
-                return null;
-            }
-        } catch (NameNotFoundException e) {
-            Log.w(TAG, "Could not load package: " + iconResource.packageName + "! NameNotFound");
-            return null;
-        } catch (NotFoundException e) {
-            Log.w(TAG, "Could not load resource: " + iconResource.resourceName + "! NotFound");
-            return null;
-        }
-    }
-
-    public final boolean isScaled() {
-        return mScaled;
-    }
-
-    private Bitmap decodeBitmap(InputStream in, BitmapWorkerOptions options)
-            throws IOException {
-        CachedInputStream bufferedStream = null;
-        BitmapFactory.Options bitmapOptions = null;
-        try {
-            bufferedStream = new CachedInputStream(in);
-            // Let the bufferedStream be able to mark unlimited bytes up to full stream length.
-            // The value that BitmapFactory uses (1024) is too small for detecting bounds
-            bufferedStream.setOverrideMarkLimit(Integer.MAX_VALUE);
-            bitmapOptions = new BitmapFactory.Options();
-            bitmapOptions.inJustDecodeBounds = true;
-            if (options.getBitmapConfig() != null) {
-                bitmapOptions.inPreferredConfig = options.getBitmapConfig();
-            }
-            bitmapOptions.inTempStorage = ByteArrayPool.get16KBPool().allocateChunk();
-            bufferedStream.mark(Integer.MAX_VALUE);
-            BitmapFactory.decodeStream(bufferedStream, null, bitmapOptions);
-
-            float heightScale = (float) bitmapOptions.outHeight / options.getHeight();
-            float widthScale = (float) bitmapOptions.outWidth / options.getWidth();
-            // We take the smaller value because we will crop the result later.
-            float scale = heightScale < widthScale ? heightScale : widthScale;
-
-            bitmapOptions.inJustDecodeBounds = false;
-            if (scale >= 4) {
-                // Sampling looks really, really bad. So sample part way and then smooth
-                // the result with bilinear interpolation.
-                bitmapOptions.inSampleSize = (int) scale / 2;
-            }
-            // Reset buffer to original position and disable the overrideMarkLimit
-            bufferedStream.reset();
-            bufferedStream.setOverrideMarkLimit(0);
-
-            Bitmap bitmap = BitmapFactory.decodeStream(bufferedStream, null, bitmapOptions);
-            // We need to check isCancelled() and throw away the result if we are cancelled because
-            // if we're loading over HTTP, canceling an AsyncTask causes the HTTP library to throw
-            // an exception, which the bitmap library then eats and returns a partially decoded
-            // bitmap. This behavior no longer will happen in lmp-mr1.
-            if (bitmap == null || isCancelled()) {
-                return null;
-            }
-
-            Bitmap result = bitmap;
-            if (options.getWidth() < bitmap.getWidth()
-                    || options.getHeight() < bitmap.getHeight()) {
-                result = BitmapUtils.scaleBitmap(bitmap, options.getWidth(), options.getHeight());
-                mScaled = true;
-            }
-
-            if (result != bitmap) {
-                bitmap.recycle();
-            }
-            return result;
-
-        } finally {
-            if (bitmapOptions != null) {
-                ByteArrayPool.get16KBPool().releaseChunk(bitmapOptions.inTempStorage);
-            }
-            if (bufferedStream != null) {
-                bufferedStream.close();
-            }
-        }
-    }
-
-    private Bitmap getBitmapFromHttp(BitmapWorkerOptions options) throws IOException {
-        URL url = new URL(options.getResourceUri().toString());
-        if (DEBUG) {
-            Log.d(TAG, "Loading " + url);
-        }
-        HttpURLConnection connection = null;
-        try {
-            connection = (HttpURLConnection) url.openConnection();
-            connection.setConnectTimeout(SOCKET_TIMEOUT);
-            connection.setReadTimeout(READ_TIMEOUT);
-            InputStream in = new BufferedInputStream(connection.getInputStream());
-            return decodeBitmap(in, options);
-        } finally {
-            if (DEBUG) {
-                Log.d(TAG, "loading done "+url);
-            }
-            if (connection != null) {
-                connection.disconnect();
-            }
-        }
-    }
-
-    private Bitmap getBitmapFromContent(BitmapWorkerOptions options) throws IOException {
-        InputStream bitmapStream =
-                options.getContext().getContentResolver().openInputStream(options.getResourceUri());
-        if (bitmapStream != null) {
-            return decodeBitmap(bitmapStream, options);
-        } else {
-            Log.w(TAG, "Content provider returned a null InputStream when trying to " +
-                    "open resource.");
-            return null;
-        }
-    }
-
-    /**
-     * load drawable for non-bitmap resource or InputStream for bitmap resource without
-     * caching Bitmap in Resources.  So that caller can maintain a different caching
-     * storage with less memory used.
-     * @return  either {@link Drawable} for xml and ColorDrawable <br>
-     *          or {@link InputStream} for Bitmap resource
-     */
-    private static Object loadDrawable(Context context, ShortcutIconResource r)
-            throws NameNotFoundException {
-        Resources resources = context.getPackageManager()
-                .getResourcesForApplication(r.packageName);
-        if (resources == null) {
-            return null;
-        }
-        resources.updateConfiguration(context.getResources().getConfiguration(),
-                context.getResources().getDisplayMetrics());
-        final int id = resources.getIdentifier(r.resourceName, null, null);
-        if (id == 0) {
-            Log.e(TAG, "Couldn't get resource " + r.resourceName + " in resources of "
-                    + r.packageName);
-            return null;
-        }
-        TypedValue value = new TypedValue();
-        resources.getValue(id, value, true);
-        if ((value.type == TypedValue.TYPE_STRING && value.string.toString().endsWith(".xml")) || (
-                value.type >= TypedValue.TYPE_FIRST_COLOR_INT
-                && value.type <= TypedValue.TYPE_LAST_COLOR_INT)) {
-            return resources.getDrawable(id);
-        }
-        return resources.openRawResource(id, value);
-    }
-
-    private static Bitmap createIconBitmap(Drawable drawable, BitmapWorkerOptions workerOptions) {
-        // Some drawables have an intrinsic width and height of -1. In that case
-        // size it to our output.
-        int width = drawable.getIntrinsicWidth();
-        if (width == -1) {
-            width = workerOptions.getWidth();
-        }
-        int height = drawable.getIntrinsicHeight();
-        if (height == -1) {
-            height = workerOptions.getHeight();
-        }
-        Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
-        Canvas canvas = new Canvas(bitmap);
-        drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
-        drawable.draw(canvas);
-        return bitmap;
-    }
-
-    public static Drawable getDrawable(Context context, ShortcutIconResource iconResource)
-            throws NameNotFoundException {
-        Resources resources =
-                context.getPackageManager().getResourcesForApplication(iconResource.packageName);
-        if (resources == null) {
-            return null;
-        }
-        resources.updateConfiguration(context.getResources().getConfiguration(),
-                context.getResources().getDisplayMetrics());
-        int id = resources.getIdentifier(iconResource.resourceName, null, null);
-        if (id == 0) {
-            throw new NameNotFoundException();
-        }
-
-        return resources.getDrawable(id);
-    }
-
-    @SuppressWarnings("deprecation")
-    private Bitmap getAccountImage(BitmapWorkerOptions options) {
-        String accountName = UriUtils.getAccountName(options.getResourceUri());
-        Context context = options.getContext();
-
-        if (accountName != null && context != null) {
-            Account thisAccount = null;
-            for (Account account : AccountManager.get(context).
-                    getAccountsByType(GOOGLE_ACCOUNT_TYPE)) {
-                if (account.name.equals(accountName)) {
-                    thisAccount = account;
-                    break;
-                }
-            }
-            if (thisAccount != null) {
-                String picUriString = AccountImageHelper.getAccountPictureUri(context, thisAccount);
-                if (picUriString != null) {
-                    BitmapWorkerOptions.Builder optionBuilder =
-                            new BitmapWorkerOptions.Builder(context)
-                            .width(options.getWidth())
-                                    .height(options.getHeight())
-                                    .cacheFlag(options.getCacheFlag())
-                                    .bitmapConfig(options.getBitmapConfig())
-                                    .resource(Uri.parse(picUriString));
-                    return BitmapDownloader.getInstance(context)
-                            .loadBitmapBlocking(optionBuilder.build());
-                }
-                return null;
-            }
-        }
-        return null;
-    }
-}
diff --git a/car-apps-common/src/com/android/car/apps/common/ByteArrayPool.java b/car-apps-common/src/com/android/car/apps/common/ByteArrayPool.java
deleted file mode 100644
index 676b7dc..0000000
--- a/car-apps-common/src/com/android/car/apps/common/ByteArrayPool.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.car.apps.common;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * @hide
- */
-public final class ByteArrayPool {
-
-    public static final int CHUNK16K = 16 * 1024;
-    public static final int DEFAULT_MAX_NUM = 8;
-
-    private final static ByteArrayPool sChunk16K = new ByteArrayPool(CHUNK16K, DEFAULT_MAX_NUM);
-
-    private final ArrayList<byte[]> mCachedBuf;
-    private final int mChunkSize;
-    private final int mMaxNum;
-
-    private ByteArrayPool(int chunkSize, int maxNum) {
-        mChunkSize = chunkSize;
-        mMaxNum = maxNum;
-        mCachedBuf = new ArrayList<byte[]>(mMaxNum);
-    }
-
-    /**
-     * get singleton of 16KB byte[] pool
-     */
-    public static ByteArrayPool get16KBPool() {
-        return sChunk16K;
-    }
-
-    public byte[] allocateChunk() {
-        synchronized (mCachedBuf) {
-            int size = mCachedBuf.size();
-            if (size > 0) {
-                return mCachedBuf.remove(size - 1);
-            }
-            return new byte[mChunkSize];
-        }
-    }
-
-    public void clear() {
-        synchronized (mCachedBuf) {
-            mCachedBuf.clear();
-        }
-    }
-
-    public void releaseChunk(byte[] buf) {
-        if (buf == null || buf.length != mChunkSize) {
-            return;
-        }
-        synchronized (mCachedBuf) {
-            if (mCachedBuf.size() < mMaxNum) {
-                mCachedBuf.add(buf);
-            }
-        }
-    }
-
-    public void releaseChunks(List<byte[]> bufs) {
-        synchronized (mCachedBuf) {
-            for (int i = 0, c = bufs.size(); i < c; i++) {
-                if (mCachedBuf.size() == mMaxNum) {
-                    break;
-                }
-                byte[] buf = bufs.get(i);
-                if (buf != null && buf.length == mChunkSize) {
-                    mCachedBuf.add(bufs.get(i));
-                }
-            }
-        }
-    }
-
-}
diff --git a/car-apps-common/src/com/android/car/apps/common/CachedInputStream.java b/car-apps-common/src/com/android/car/apps/common/CachedInputStream.java
deleted file mode 100644
index f365424..0000000
--- a/car-apps-common/src/com/android/car/apps/common/CachedInputStream.java
+++ /dev/null
@@ -1,260 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.car.apps.common;
-
-import java.io.FilterInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * A replacement of BufferedInputStream (no multiple thread): <p>
- * - use list of byte array (chunks) instead of keep growing a single byte array (more efficent)
- *   <br>
- * - support overriding the markLimit passed in mark() call (The value that BitmapFactory
- *   uses 1024 is too small for detecting bitmap bounds and reset()) <br>
- * @hide
- */
-public class CachedInputStream extends FilterInputStream {
-
-    private static final int CHUNK_SIZE = ByteArrayPool.CHUNK16K;
-
-    private ArrayList<byte[]> mBufs = new ArrayList<byte[]>();
-    private int mPos = 0;  // current read position inside the chunk buffers
-    private int mCount = 0; // total validate bytes in chunk buffers
-    private int mMarkPos = -1; // marked read position in chunk buffers
-    private int mOverrideMarkLimit; // to override readlimit of mark() call
-    private int mMarkLimit; // effective marklimit
-    private byte[] tmp = new byte[1]; // tmp buffer used in read()
-
-    public CachedInputStream(InputStream in) {
-        super(in);
-    }
-
-    @Override
-    public boolean markSupported() {
-        return true;
-    }
-
-    /**
-     * set the value that will override small readlimit passed in mark() call.
-     */
-    public void setOverrideMarkLimit(int overrideMarkLimit) {
-        mOverrideMarkLimit = overrideMarkLimit;
-    }
-
-    public int getOverrideMarkLimit() {
-        return mOverrideMarkLimit;
-    }
-
-    @Override
-    public void mark(int readlimit) {
-        readlimit = readlimit < mOverrideMarkLimit ? mOverrideMarkLimit : readlimit;
-        if (mMarkPos >= 0) {
-            // for replacing existing mark(), discard anything before mPos
-            // and move mMarkPos to mPos
-            int chunks = mPos / CHUNK_SIZE;
-            if (chunks > 0) {
-                // trim the header buffers
-                int removedBytes = chunks * CHUNK_SIZE;
-                List<byte[]> subList = mBufs.subList(0, chunks);
-                releaseChunks(subList);
-                subList.clear();
-                mPos = mPos - removedBytes;
-                mCount = mCount - removedBytes;
-            }
-        }
-        mMarkPos = mPos;
-        mMarkLimit = readlimit;
-    }
-
-    @Override
-    public void reset() throws IOException {
-        if (mMarkPos < 0) {
-            throw new IOException("mark has been invalidated");
-        }
-        mPos = mMarkPos;
-    }
-
-    @Override
-    public int read() throws IOException {
-        // TODO, not efficient, but the function is not called by BitmapFactory
-        int r = read(tmp, 0, 1);
-        if (r <= 0) {
-            return -1;
-        }
-        return tmp[0] & 0xFF;
-    }
-
-    @Override
-    public void close() throws IOException {
-        if (in!=null) {
-            in.close();
-            in = null;
-        }
-        releaseChunks(mBufs);
-    }
-
-    private static void releaseChunks(List<byte[]> bufs) {
-        ByteArrayPool.get16KBPool().releaseChunks(bufs);
-    }
-
-    private byte[] allocateChunk() {
-        return ByteArrayPool.get16KBPool().allocateChunk();
-    }
-
-    private boolean invalidate() {
-        if (mCount - mMarkPos > mMarkLimit) {
-            mMarkPos = -1;
-            mCount = 0;
-            mPos = 0;
-            releaseChunks(mBufs);
-            mBufs.clear();
-            return true;
-        }
-        return false;
-    }
-
-    @Override
-    public int read(byte[] buffer, int offset, int count) throws IOException {
-        if (in == null) {
-            throw streamClosed();
-        }
-        if (mMarkPos == -1) {
-            int reads = in.read(buffer, offset, count);
-            return reads;
-        }
-        if (count == 0) {
-            return 0;
-        }
-        int copied = copyMarkedBuffer(buffer, offset, count);
-        count -= copied;
-        offset += copied;
-        int totalReads = copied;
-        while (count > 0) {
-            if (mPos == mBufs.size() * CHUNK_SIZE) {
-                mBufs.add(allocateChunk());
-            }
-            int currentBuf = mPos / CHUNK_SIZE;
-            int indexInBuf = mPos - currentBuf * CHUNK_SIZE;
-            byte[] buf = mBufs.get(currentBuf);
-            int end = (currentBuf + 1) * CHUNK_SIZE;
-            int leftInBuffer = end - mPos;
-            int toRead = count > leftInBuffer ? leftInBuffer : count;
-            int reads = in.read(buf, indexInBuf, toRead);
-            if (reads > 0) {
-                System.arraycopy(buf, indexInBuf, buffer, offset, reads);
-                mPos += reads;
-                mCount += reads;
-                totalReads += reads;
-                offset += reads;
-                count -= reads;
-                if (invalidate()) {
-                    reads = in.read(buffer, offset, count);
-                    if (reads >0 ) {
-                        totalReads += reads;
-                    }
-                    break;
-                }
-            } else {
-                break;
-            }
-        }
-        if (totalReads == 0) {
-            return -1;
-        }
-        return totalReads;
-    }
-
-    private int copyMarkedBuffer(byte[] buffer, int offset, int read) {
-        int totalRead = 0;
-        while (read > 0 && mPos < mCount) {
-            int currentBuf = mPos / CHUNK_SIZE;
-            int indexInBuf = mPos - currentBuf * CHUNK_SIZE;
-            byte[] buf = mBufs.get(currentBuf);
-            int end = (currentBuf + 1) * CHUNK_SIZE;
-            if (end > mCount) {
-                end = mCount;
-            }
-            int leftInBuffer = end - mPos;
-            int toRead = read > leftInBuffer ? leftInBuffer : read;
-            System.arraycopy(buf, indexInBuf, buffer, offset, toRead);
-            offset += toRead;
-            read -= toRead;
-            totalRead += toRead;
-            mPos += toRead;
-        }
-        return totalRead;
-    }
-
-    @Override
-    public int available() throws IOException {
-        if (in == null) {
-            throw streamClosed();
-        }
-        return mCount - mPos + in.available();
-    }
-
-    @Override
-    public long skip(long byteCount) throws IOException {
-        if (in == null) {
-            throw streamClosed();
-        }
-        if (mMarkPos <0) {
-            return in.skip(byteCount);
-        }
-        long totalSkip = 0;
-        totalSkip = mCount - mPos;
-        if (totalSkip > byteCount) {
-            totalSkip = byteCount;
-        }
-        mPos += totalSkip;
-        byteCount -= totalSkip;
-        while (byteCount > 0) {
-            if (mPos == mBufs.size() * CHUNK_SIZE) {
-                mBufs.add(allocateChunk());
-            }
-            int currentBuf = mPos / CHUNK_SIZE;
-            int indexInBuf = mPos - currentBuf * CHUNK_SIZE;
-            byte[] buf = mBufs.get(currentBuf);
-            int end = (currentBuf + 1) * CHUNK_SIZE;
-            int leftInBuffer = end - mPos;
-            int toRead = (int) (byteCount > leftInBuffer ? leftInBuffer : byteCount);
-            int reads = in.read(buf, indexInBuf, toRead);
-            if (reads > 0) {
-                mPos += reads;
-                mCount += reads;
-                byteCount -= reads;
-                totalSkip += reads;
-                if (invalidate()) {
-                    if (byteCount > 0) {
-                        totalSkip += in.skip(byteCount);
-                    }
-                    break;
-                }
-            } else {
-                break;
-            }
-        }
-        return totalSkip;
-    }
-
-    private static IOException streamClosed() {
-        return new IOException("stream closed");
-    }
-
-}
diff --git a/car-apps-common/src/com/android/car/apps/common/DrawableDownloader.java b/car-apps-common/src/com/android/car/apps/common/DrawableDownloader.java
deleted file mode 100644
index a13fb18..0000000
--- a/car-apps-common/src/com/android/car/apps/common/DrawableDownloader.java
+++ /dev/null
@@ -1,406 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.car.apps.common;
-
-import android.app.ActivityManager;
-import android.content.Context;
-import android.content.Intent.ShortcutIconResource;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.graphics.Bitmap;
-import android.graphics.drawable.BitmapDrawable;
-import android.graphics.drawable.Drawable;
-import android.util.Log;
-import android.util.LruCache;
-import android.widget.ImageView;
-
-import java.lang.ref.SoftReference;
-import java.util.ArrayList;
-import java.util.concurrent.Executor;
-import java.util.concurrent.Executors;
-
-/**
- * Downloader class which loads a resource URI into an image view or triggers a callback
- * <p>
- * This class adds a LRU cache over DrawableLoader.
- * <p>
- * Calling getBitmap() or loadBitmap() will return a RefcountBitmapDrawable with initial refcount =
- * 2 by the cache table and by caller.  You must call releaseRef() when you are done with the resource.
- * The most common way is using RefcountImageView, and releaseRef() for you.  Once both RefcountImageView
- * and LRUCache removes the refcount, the underlying bitmap will be used for decoding new bitmap.
- * <p>
- * If the URI does not point to a bitmap (e.g. point to a drawable xml, we won't cache it and we
- * directly return a regular Drawable).
- */
-public class DrawableDownloader {
-
-    private static final String TAG = "DrawableDownloader";
-
-    private static final boolean DEBUG = false;
-
-    private static final int CORE_POOL_SIZE = 5;
-
-    // thread pool for loading non android-resources such as http,  content
-    private static final Executor BITMAP_DOWNLOADER_THREAD_POOL_EXECUTOR =
-            Executors.newFixedThreadPool(CORE_POOL_SIZE);
-
-    private static final int CORE_RESOURCE_POOL_SIZE = 1;
-
-    // thread pool for loading android resources,  we use separate thread pool so
-    // that network loading will not block local android icons
-    private static final Executor BITMAP_RESOURCE_DOWNLOADER_THREAD_POOL_EXECUTOR =
-            Executors.newFixedThreadPool(CORE_RESOURCE_POOL_SIZE);
-
-    // 1/4 of max memory is used for bitmap mem cache
-    private static final int MEM_TO_CACHE = 4;
-
-    // hard limit for bitmap mem cache in MB
-    private static final int CACHE_HARD_LIMIT = 32;
-
-    /**
-     * bitmap cache item structure saved in LruCache
-     */
-    private static class BitmapItem {
-        int mOriginalWidth;
-        int mOriginalHeight;
-        ArrayList<BitmapDrawable> mBitmaps = new ArrayList<BitmapDrawable>(3);
-        int mByteCount;
-        public BitmapItem(int originalWidth, int originalHeight) {
-            mOriginalWidth = originalWidth;
-            mOriginalHeight = originalHeight;
-        }
-
-        // get bitmap from the list
-        BitmapDrawable findDrawable(BitmapWorkerOptions options) {
-            for (int i = 0, c = mBitmaps.size(); i < c; i++) {
-                BitmapDrawable d = mBitmaps.get(i);
-                // use drawable with original size
-                if (d.getIntrinsicWidth() == mOriginalWidth
-                        && d.getIntrinsicHeight() == mOriginalHeight) {
-                    return d;
-                }
-                // if specified width/height in options and is smaller than
-                // cached one, we can use this cached drawable
-                if (options.getHeight() != BitmapWorkerOptions.MAX_IMAGE_DIMENSION_PX) {
-                    if (options.getHeight() <= d.getIntrinsicHeight()) {
-                        return d;
-                    }
-                } else if (options.getWidth() != BitmapWorkerOptions.MAX_IMAGE_DIMENSION_PX) {
-                    if (options.getWidth() <= d.getIntrinsicWidth()) {
-                        return d;
-                    }
-                }
-            }
-            return null;
-        }
-
-        @SuppressWarnings("unused")
-        BitmapDrawable findLargestDrawable(BitmapWorkerOptions options) {
-            return mBitmaps.size() == 0 ? null : mBitmaps.get(0);
-        }
-
-        void addDrawable(BitmapDrawable d) {
-            int i = 0, c = mBitmaps.size();
-            for (; i < c; i++) {
-                BitmapDrawable drawable = mBitmaps.get(i);
-                if (drawable.getIntrinsicHeight() < d.getIntrinsicHeight()) {
-                    break;
-                }
-            }
-            mBitmaps.add(i, d);
-            mByteCount += RecycleBitmapPool.getSize(d.getBitmap());
-        }
-
-        void clear() {
-            for (int i = 0, c = mBitmaps.size(); i < c; i++) {
-                BitmapDrawable d = mBitmaps.get(i);
-                if (d instanceof RefcountBitmapDrawable) {
-                    ((RefcountBitmapDrawable) d).getRefcountObject().releaseRef();
-                }
-            }
-            mBitmaps.clear();
-            mByteCount = 0;
-        }
-    }
-
-    public static abstract class BitmapCallback {
-        SoftReference<DrawableLoader> mTask;
-
-        public abstract void onBitmapRetrieved(Drawable bitmap);
-    }
-
-    private Context mContext;
-    private LruCache<String, BitmapItem> mMemoryCache;
-    private RecycleBitmapPool mRecycledBitmaps;
-
-    private static DrawableDownloader sBitmapDownloader;
-
-    private static final Object sBitmapDownloaderLock = new Object();
-
-    /**
-     * get the singleton BitmapDownloader for the application
-     */
-    public final static DrawableDownloader getInstance(Context context) {
-        if (sBitmapDownloader == null) {
-            synchronized(sBitmapDownloaderLock) {
-                if (sBitmapDownloader == null) {
-                    sBitmapDownloader = new DrawableDownloader(context);
-                }
-            }
-        }
-        return sBitmapDownloader;
-    }
-
-    private static String getBucketKey(String baseKey, Bitmap.Config bitmapConfig) {
-        return new StringBuilder(baseKey.length() + 16).append(baseKey)
-                         .append(":").append(bitmapConfig == null ? "" : bitmapConfig.ordinal())
-                         .toString();
-     }
-
-    public static Drawable getDrawable(Context context, ShortcutIconResource iconResource)
-            throws NameNotFoundException {
-        return DrawableLoader.getDrawable(context, iconResource);
-    }
-
-    private DrawableDownloader(Context context) {
-        mContext = context;
-        int memClass = ((ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE))
-                .getMemoryClass();
-        memClass = memClass / MEM_TO_CACHE;
-        if (memClass > CACHE_HARD_LIMIT) {
-            memClass = CACHE_HARD_LIMIT;
-        }
-        int cacheSize = 1024 * 1024 * memClass;
-        mMemoryCache = new LruCache<String, BitmapItem>(cacheSize) {
-            @Override
-            protected int sizeOf(String key, BitmapItem bitmap) {
-                return bitmap.mByteCount;
-            }
-            @Override
-            protected void entryRemoved(
-                    boolean evicted, String key, BitmapItem oldValue, BitmapItem newValue) {
-                if (evicted) {
-                    oldValue.clear();
-                }
-            }
-        };
-        mRecycledBitmaps = new RecycleBitmapPool();
-    }
-
-    /**
-     * trim memory cache to 0~1 * maxSize
-     */
-    public void trimTo(float amount) {
-        if (amount == 0f) {
-            mMemoryCache.evictAll();
-        } else {
-            mMemoryCache.trimToSize((int) (amount * mMemoryCache.maxSize()));
-        }
-    }
-
-    /**
-     * load bitmap in current thread, will *block* current thread.
-     * @deprecated
-     */
-    @Deprecated
-    public final Drawable loadBitmapBlocking(BitmapWorkerOptions options) {
-        final boolean hasAccountImageUri = UriUtils.isAccountImageUri(options.getResourceUri());
-        Drawable bitmap = null;
-        if (hasAccountImageUri) {
-            AccountImageChangeObserver.getInstance().registerChangeUriIfPresent(options);
-        } else {
-            bitmap = getBitmapFromMemCache(options);
-        }
-
-        if (bitmap == null) {
-            DrawableLoader task = new DrawableLoader(null, mRecycledBitmaps) {
-                @Override
-                protected Drawable doInBackground(BitmapWorkerOptions... params) {
-                    final Drawable bitmap = super.doInBackground(params);
-                    if (bitmap != null && !hasAccountImageUri) {
-                        addBitmapToMemoryCache(params[0], bitmap, this);
-                    }
-                    return bitmap;
-                }
-            };
-            return task.doInBackground(options);
-        }
-        return bitmap;
-    }
-
-    /**
-     * Loads the bitmap into the image view.
-     */
-    public void loadBitmap(BitmapWorkerOptions options, final ImageView imageView) {
-        cancelDownload(imageView);
-        final boolean hasAccountImageUri = UriUtils.isAccountImageUri(options.getResourceUri());
-        Drawable bitmap = null;
-        if (hasAccountImageUri) {
-            AccountImageChangeObserver.getInstance().registerChangeUriIfPresent(options);
-        } else {
-            bitmap = getBitmapFromMemCache(options);
-        }
-
-        if (bitmap != null) {
-            imageView.setImageDrawable(bitmap);
-        } else {
-            DrawableLoader task = new DrawableLoader(imageView, mRecycledBitmaps) {
-                @Override
-                protected Drawable doInBackground(BitmapWorkerOptions... params) {
-                    Drawable bitmap = super.doInBackground(params);
-                    if (bitmap != null && !hasAccountImageUri) {
-                        addBitmapToMemoryCache(params[0], bitmap, this);
-                    }
-                    return bitmap;
-                }
-            };
-            imageView.setTag(R.id.imageDownloadTask, new SoftReference<DrawableLoader>(task));
-            scheduleTask(task, options);
-        }
-    }
-
-    /**
-     * Loads the bitmap.
-     * <p>
-     * This will be sent back to the callback object.
-     */
-    public void getBitmap(BitmapWorkerOptions options, final BitmapCallback callback) {
-        cancelDownload(callback);
-        final boolean hasAccountImageUri = UriUtils.isAccountImageUri(options.getResourceUri());
-        final Drawable bitmap = hasAccountImageUri ? null : getBitmapFromMemCache(options);
-        if (hasAccountImageUri) {
-            AccountImageChangeObserver.getInstance().registerChangeUriIfPresent(options);
-        }
-
-        if (bitmap != null) {
-            callback.onBitmapRetrieved(bitmap);
-            return;
-        }
-        DrawableLoader task = new DrawableLoader(null, mRecycledBitmaps) {
-            @Override
-            protected Drawable doInBackground(BitmapWorkerOptions... params) {
-                final Drawable bitmap = super.doInBackground(params);
-                if (bitmap != null && !hasAccountImageUri) {
-                    addBitmapToMemoryCache(params[0], bitmap, this);
-                }
-                return bitmap;
-            }
-
-            @Override
-            protected void onPostExecute(Drawable bitmap) {
-                callback.onBitmapRetrieved(bitmap);
-            }
-        };
-        callback.mTask = new SoftReference<DrawableLoader>(task);
-        scheduleTask(task, options);
-    }
-
-    private static void scheduleTask(DrawableLoader task, BitmapWorkerOptions options) {
-        if (options.isFromResource()) {
-            task.executeOnExecutor(BITMAP_RESOURCE_DOWNLOADER_THREAD_POOL_EXECUTOR, options);
-        } else {
-            task.executeOnExecutor(BITMAP_DOWNLOADER_THREAD_POOL_EXECUTOR, options);
-        }
-    }
-
-    /**
-     * Cancel download<p>
-     * @param key {@link BitmapCallback} or {@link ImageView}
-     */
-    @SuppressWarnings("unchecked")
-    public boolean cancelDownload(Object key) {
-        DrawableLoader task = null;
-        if (key instanceof ImageView) {
-            ImageView imageView = (ImageView)key;
-            SoftReference<DrawableLoader> softReference =
-                    (SoftReference<DrawableLoader>) imageView.getTag(R.id.imageDownloadTask);
-            if (softReference != null) {
-                task = softReference.get();
-                softReference.clear();
-            }
-        } else if (key instanceof BitmapCallback) {
-            BitmapCallback callback = (BitmapCallback)key;
-            if (callback.mTask != null) {
-                task = callback.mTask.get();
-                callback.mTask = null;
-            }
-        }
-        if (task != null) {
-            return task.cancel(true);
-        }
-        return false;
-    }
-
-    private void addBitmapToMemoryCache(BitmapWorkerOptions key, Drawable bitmap,
-            DrawableLoader loader) {
-        if (!key.isMemCacheEnabled()) {
-            return;
-        }
-        if (!(bitmap instanceof BitmapDrawable)) {
-            return;
-        }
-        String bucketKey = getBucketKey(key.getCacheKey(), key.getBitmapConfig());
-        BitmapItem bitmapItem = mMemoryCache.get(bucketKey);
-        if (DEBUG) {
-            Log.d(TAG, "add cache "+bucketKey);
-        }
-        if (bitmapItem != null) {
-            // remove and re-add to update size
-            mMemoryCache.remove(bucketKey);
-        } else {
-            bitmapItem = new BitmapItem(loader.getOriginalWidth(), loader.getOriginalHeight());
-        }
-        if (bitmap instanceof RefcountBitmapDrawable) {
-            RefcountBitmapDrawable refcountDrawable = (RefcountBitmapDrawable) bitmap;
-            refcountDrawable.getRefcountObject().addRef();
-        }
-        bitmapItem.addDrawable((BitmapDrawable) bitmap);
-        mMemoryCache.put(bucketKey, bitmapItem);
-    }
-
-    private Drawable getBitmapFromMemCache(BitmapWorkerOptions key) {
-        String bucketKey =
-                getBucketKey(key.getCacheKey(), key.getBitmapConfig());
-        BitmapItem item = mMemoryCache.get(bucketKey);
-        if (item != null) {
-            return createRefCopy(item.findDrawable(key));
-        }
-        return null;
-    }
-
-    public BitmapDrawable getLargestBitmapFromMemCache(BitmapWorkerOptions key) {
-        String bucketKey =
-                getBucketKey(key.getCacheKey(), key.getBitmapConfig());
-        BitmapItem item = mMemoryCache.get(bucketKey);
-        if (item != null) {
-            return (BitmapDrawable) createRefCopy(item.findLargestDrawable(key));
-        }
-        return null;
-    }
-
-    private Drawable createRefCopy(Drawable d) {
-        if (d != null) {
-            if (d instanceof RefcountBitmapDrawable) {
-                RefcountBitmapDrawable refcountDrawable = (RefcountBitmapDrawable) d;
-                refcountDrawable.getRefcountObject().addRef();
-                d = new RefcountBitmapDrawable(mContext.getResources(),
-                        refcountDrawable);
-            }
-            return d;
-        }
-        return null;
-    }
-
-}
diff --git a/car-apps-common/src/com/android/car/apps/common/DrawableLoader.java b/car-apps-common/src/com/android/car/apps/common/DrawableLoader.java
deleted file mode 100644
index a9379f0..0000000
--- a/car-apps-common/src/com/android/car/apps/common/DrawableLoader.java
+++ /dev/null
@@ -1,387 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.car.apps.common;
-
-import android.accounts.Account;
-import android.accounts.AccountManager;
-import android.content.Context;
-import android.content.Intent.ShortcutIconResource;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.content.res.Resources;
-import android.content.res.Resources.NotFoundException;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.graphics.drawable.Drawable;
-import android.net.Uri;
-import android.os.AsyncTask;
-import android.util.Log;
-import android.util.TypedValue;
-import android.widget.ImageView;
-
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.lang.ref.WeakReference;
-import java.net.SocketTimeoutException;
-import java.net.URL;
-import java.net.URLConnection;
-
-/**
- * AsyncTask which loads a bitmap.
- * <p>
- * The source of this can be another package (via a resource), a URI (content provider), or
- * a file path.
- * @see BitmapWorkerOptions
- * @hide
- */
-class DrawableLoader extends AsyncTask<BitmapWorkerOptions, Void, Drawable> {
-
-    private static final String TAG = "DrawableLoader";
-    private static final String GOOGLE_ACCOUNT_TYPE = "com.google";
-
-    private static final boolean DEBUG = false;
-
-    private static final int SOCKET_TIMEOUT = 10000;
-    private static final int READ_TIMEOUT = 10000;
-
-    private final WeakReference<ImageView> mImageView;
-    private int mOriginalWidth;
-    private int mOriginalHeight;
-    private final RecycleBitmapPool mRecycledBitmaps;
-
-    private final RefcountObject.RefcountListener mRefcountListener =
-            new RefcountObject.RefcountListener() {
-        @Override
-        @SuppressWarnings("rawtypes")
-        public void onRefcountZero(RefcountObject object) {
-            mRecycledBitmaps.addRecycledBitmap((Bitmap) object.getObject());
-        }
-    };
-
-
-    DrawableLoader(ImageView imageView, RecycleBitmapPool recycledBitmapPool) {
-        mImageView = new WeakReference<ImageView>(imageView);
-        mRecycledBitmaps = recycledBitmapPool;
-    }
-
-    public int getOriginalWidth() {
-        return mOriginalWidth;
-    }
-
-    public int getOriginalHeight() {
-        return mOriginalHeight;
-    }
-
-    @Override
-    protected Drawable doInBackground(BitmapWorkerOptions... params) {
-
-        return retrieveDrawable(params[0]);
-    }
-
-    protected Drawable retrieveDrawable(BitmapWorkerOptions workerOptions) {
-        try {
-            if (workerOptions.getIconResource() != null) {
-                return getBitmapFromResource(workerOptions.getIconResource(), workerOptions);
-            } else if (workerOptions.getResourceUri() != null) {
-                if (UriUtils.isAndroidResourceUri(workerOptions.getResourceUri())
-                        || UriUtils.isShortcutIconResourceUri(workerOptions.getResourceUri())) {
-                    // Make an icon resource from this.
-                    return getBitmapFromResource(
-                            UriUtils.getIconResource(workerOptions.getResourceUri()),
-                            workerOptions);
-                } else if (UriUtils.isWebUri(workerOptions.getResourceUri())) {
-                    return getBitmapFromHttp(workerOptions);
-                } else if (UriUtils.isContentUri(workerOptions.getResourceUri())) {
-                    return getBitmapFromContent(workerOptions);
-                } else if (UriUtils.isAccountImageUri(workerOptions.getResourceUri())) {
-                    return getAccountImage(workerOptions);
-                } else {
-                    Log.e(TAG, "Error loading bitmap - unknown resource URI! "
-                            + workerOptions.getResourceUri());
-                }
-            } else {
-                Log.e(TAG, "Error loading bitmap - no source!");
-            }
-        } catch (IOException e) {
-            Log.e(TAG, "Error loading url " + workerOptions.getResourceUri(), e);
-            return null;
-        } catch (RuntimeException e) {
-            Log.e(TAG, "Critical Error loading url " + workerOptions.getResourceUri(), e);
-            return null;
-        }
-
-        return null;
-    }
-
-    @Override
-    protected void onPostExecute(Drawable bitmap) {
-        if (mImageView != null) {
-            final ImageView imageView = mImageView.get();
-            if (imageView != null) {
-                imageView.setImageDrawable(bitmap);
-            }
-        }
-    }
-
-    @Override
-    protected void onCancelled(Drawable result) {
-        if (result instanceof RefcountBitmapDrawable) {
-            // Remove the extra refcount created by us,  DrawableDownloader LruCache
-            // still holds one to the bitmap
-            RefcountBitmapDrawable d = (RefcountBitmapDrawable) result;
-            d.getRefcountObject().releaseRef();
-        }
-    }
-
-    private Drawable getBitmapFromResource(ShortcutIconResource iconResource,
-            BitmapWorkerOptions outputOptions) throws IOException {
-        if (DEBUG) {
-            Log.d(TAG, "Loading " + iconResource.toString());
-        }
-        try {
-            Object drawable = loadDrawable(outputOptions.getContext(), iconResource);
-            if (drawable instanceof InputStream) {
-                // Most of these are bitmaps, so resize properly.
-                return decodeBitmap((InputStream)drawable, outputOptions);
-            } else if (drawable instanceof Drawable){
-                Drawable d = (Drawable) drawable;
-                mOriginalWidth = d.getIntrinsicWidth();
-                mOriginalHeight = d.getIntrinsicHeight();
-                return d;
-            } else {
-                Log.w(TAG, "getBitmapFromResource failed, unrecognized resource: " + drawable);
-                return null;
-            }
-        } catch (NameNotFoundException e) {
-            Log.w(TAG, "Could not load package: " + iconResource.packageName + "! NameNotFound");
-            return null;
-        } catch (NotFoundException e) {
-            Log.w(TAG, "Could not load resource: " + iconResource.resourceName + "! NotFound");
-            return null;
-        }
-    }
-
-    private Drawable decodeBitmap(InputStream in, BitmapWorkerOptions options)
-            throws IOException {
-        CachedInputStream bufferedStream = null;
-        BitmapFactory.Options bitmapOptions = null;
-        try {
-            bufferedStream = new CachedInputStream(in);
-            // Let the bufferedStream be able to mark unlimited bytes up to full stream length.
-            // The value that BitmapFactory uses (1024) is too small for detecting bounds
-            bufferedStream.setOverrideMarkLimit(Integer.MAX_VALUE);
-            bitmapOptions = new BitmapFactory.Options();
-            bitmapOptions.inJustDecodeBounds = true;
-            if (options.getBitmapConfig() != null) {
-                bitmapOptions.inPreferredConfig = options.getBitmapConfig();
-            }
-            bitmapOptions.inTempStorage = ByteArrayPool.get16KBPool().allocateChunk();
-            bufferedStream.mark(Integer.MAX_VALUE);
-            BitmapFactory.decodeStream(bufferedStream, null, bitmapOptions);
-
-            mOriginalWidth = bitmapOptions.outWidth;
-            mOriginalHeight = bitmapOptions.outHeight;
-            int heightScale = 1;
-            int height = options.getHeight();
-            if (height > 0) {
-                heightScale = bitmapOptions.outHeight / height;
-            }
-
-            int widthScale = 1;
-            int width = options.getWidth();
-            if (width > 0) {
-                widthScale = bitmapOptions.outWidth / width;
-            }
-
-            int scale = heightScale > widthScale ? heightScale : widthScale;
-            if (scale <= 1) {
-                scale = 1;
-            } else {
-                int shift = 0;
-                do {
-                    scale >>= 1;
-                    shift++;
-                } while (scale != 0);
-                scale = 1 << (shift - 1);
-            }
-
-            if (DEBUG) {
-                Log.d("BitmapWorkerTask", "Source bitmap: (" + bitmapOptions.outWidth + "x"
-                        + bitmapOptions.outHeight + ").  Max size: (" + options.getWidth() + "x"
-                        + options.getHeight() + ").  Chosen scale: " + scale + " -> " + scale);
-            }
-
-            // Reset buffer to original position and disable the overrideMarkLimit
-            bufferedStream.reset();
-            bufferedStream.setOverrideMarkLimit(0);
-            Bitmap bitmap = null;
-            try {
-                bitmapOptions.inJustDecodeBounds = false;
-                bitmapOptions.inSampleSize = scale;
-                bitmapOptions.inMutable = true;
-                bitmapOptions.inBitmap = mRecycledBitmaps.getRecycledBitmap(
-                        mOriginalWidth / scale, mOriginalHeight / scale);
-                bitmap = BitmapFactory.decodeStream(bufferedStream, null, bitmapOptions);
-            } catch (RuntimeException ex) {
-                Log.e(TAG, "RuntimeException" + ex + ", trying decodeStream again");
-                bufferedStream.reset();
-                bufferedStream.setOverrideMarkLimit(0);
-                bitmapOptions.inBitmap = null;
-                bitmap = BitmapFactory.decodeStream(bufferedStream, null, bitmapOptions);
-            }
-            if (bitmap == null) {
-                Log.d(TAG, "bitmap was null");
-                return null;
-            }
-            RefcountObject<Bitmap> object = new RefcountObject<Bitmap>(bitmap);
-            object.addRef();
-            object.setRefcountListener(mRefcountListener);
-            RefcountBitmapDrawable d = new RefcountBitmapDrawable(
-                    options.getContext().getResources(), object);
-            return d;
-        } finally {
-            Log.w(TAG, "couldn't load bitmap, releasing resources");
-            if (bitmapOptions != null) {
-                ByteArrayPool.get16KBPool().releaseChunk(bitmapOptions.inTempStorage);
-            }
-            if (bufferedStream != null) {
-                bufferedStream.close();
-            }
-        }
-    }
-
-    private Drawable getBitmapFromHttp(BitmapWorkerOptions options) throws IOException {
-        URL url = new URL(options.getResourceUri().toString());
-        if (DEBUG) {
-            Log.d(TAG, "Loading " + url);
-        }
-        try {
-            // TODO use volley for better disk cache
-            URLConnection connection = url.openConnection();
-            connection.setConnectTimeout(SOCKET_TIMEOUT);
-            connection.setReadTimeout(READ_TIMEOUT);
-            InputStream in = connection.getInputStream();
-            return decodeBitmap(in, options);
-        } catch (SocketTimeoutException e) {
-            Log.e(TAG, "loading " + url + " timed out");
-        }
-        return null;
-    }
-
-    private Drawable getBitmapFromContent(BitmapWorkerOptions options)
-            throws IOException {
-        Uri resourceUri = options.getResourceUri();
-        if (resourceUri != null) {
-            try {
-                InputStream bitmapStream =
-                        options.getContext().getContentResolver().openInputStream(resourceUri);
-
-                if (bitmapStream != null) {
-                    return decodeBitmap(bitmapStream, options);
-                } else {
-                    Log.w(TAG, "Content provider returned a null InputStream when trying to " +
-                            "open resource.");
-                    return null;
-                }
-            } catch (FileNotFoundException e) {
-                Log.e(TAG, "FileNotFoundException during openInputStream for uri: "
-                        + resourceUri.toString());
-                return null;
-            }
-        } else {
-            Log.w(TAG, "Get null resourceUri from BitmapWorkerOptions.");
-            return null;
-        }
-    }
-
-    /**
-     * load drawable for non-bitmap resource or InputStream for bitmap resource without
-     * caching Bitmap in Resources.  So that caller can maintain a different caching
-     * storage with less memory used.
-     * @return  either {@link Drawable} for xml and ColorDrawable <br>
-     *          or {@link InputStream} for Bitmap resource
-     */
-    private static Object loadDrawable(Context context, ShortcutIconResource r)
-            throws NameNotFoundException {
-        Resources resources = context.getPackageManager()
-                .getResourcesForApplication(r.packageName);
-        if (resources == null) {
-            return null;
-        }
-        resources.updateConfiguration(context.getResources().getConfiguration(),
-                context.getResources().getDisplayMetrics());
-        final int id = resources.getIdentifier(r.resourceName, null, null);
-        if (id == 0) {
-            Log.e(TAG, "Couldn't get resource " + r.resourceName + " in resources of "
-                    + r.packageName);
-            return null;
-        }
-        TypedValue value = new TypedValue();
-        resources.getValue(id, value, true);
-        if ((value.type == TypedValue.TYPE_STRING && value.string.toString().endsWith(".xml")) || (
-                value.type >= TypedValue.TYPE_FIRST_COLOR_INT
-                && value.type <= TypedValue.TYPE_LAST_COLOR_INT)) {
-            return resources.getDrawable(id);
-        }
-        return resources.openRawResource(id, value);
-    }
-
-    public static Drawable getDrawable(Context context, ShortcutIconResource iconResource)
-            throws NameNotFoundException {
-        Resources resources =
-                context.getPackageManager().getResourcesForApplication(iconResource.packageName);
-        resources.updateConfiguration(context.getResources().getConfiguration(),
-                context.getResources().getDisplayMetrics());
-        int id = resources.getIdentifier(iconResource.resourceName, null, null);
-        if (id == 0) {
-            throw new NameNotFoundException();
-        }
-        return resources.getDrawable(id);
-    }
-
-    @SuppressWarnings("deprecation")
-    private Drawable getAccountImage(BitmapWorkerOptions options) {
-        String accountName = UriUtils.getAccountName(options.getResourceUri());
-        Context context = options.getContext();
-
-        if (accountName != null && context != null) {
-            Account thisAccount = null;
-            for (Account account : AccountManager.get(context).
-                    getAccountsByType(GOOGLE_ACCOUNT_TYPE)) {
-                if (account.name.equals(accountName)) {
-                    thisAccount = account;
-                    break;
-                }
-            }
-            if (thisAccount != null) {
-                String picUriString = AccountImageHelper.getAccountPictureUri(context, thisAccount);
-                if (picUriString != null) {
-                    BitmapWorkerOptions.Builder optionBuilder =
-                            new BitmapWorkerOptions.Builder(context)
-                            .width(options.getWidth())
-                                    .height(options.getHeight())
-                                    .cacheFlag(options.getCacheFlag())
-                                    .bitmapConfig(options.getBitmapConfig())
-                                    .resource(Uri.parse(picUriString));
-                    return DrawableDownloader.getInstance(context)
-                            .loadBitmapBlocking(optionBuilder.build());
-                }
-                return null;
-            }
-        }
-        return null;
-    }
-}
diff --git a/car-apps-common/src/com/android/car/apps/common/RecycleBitmapPool.java b/car-apps-common/src/com/android/car/apps/common/RecycleBitmapPool.java
deleted file mode 100644
index 480ae00..0000000
--- a/car-apps-common/src/com/android/car/apps/common/RecycleBitmapPool.java
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.car.apps.common;
-
-import android.graphics.Bitmap;
-import android.util.Log;
-import android.util.SparseArray;
-
-import java.lang.ref.SoftReference;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-
-
-/**
- * This class saves recycle bitmap as SoftReference,  which is too vulnerable to
- * be garbage collected due to other part of application is re-allocating lots of
- * memory,  we will lose all SoftReference in a GC run.  We should maintain
- * certain amount of recycled bitmaps in memory, we may also need remove bitmap from LRUCache
- * if we are not able to get a recycled bitmap here.
- *
- * @hide
- */
-public class RecycleBitmapPool {
-
-    private static final String TAG = "RecycleBitmapPool";
-    private static final boolean DEBUG = false;
-    // allow reuse bitmap with larger bytes, set to 0 to disable different byte size
-    private static final int LARGER_BITMAP_ALLOWED_REUSE = 0;
-    private static final boolean LARGER_BITMAP_ALLOWED = LARGER_BITMAP_ALLOWED_REUSE > 0;
-
-    private static Method sGetAllocationByteCount;
-
-    static {
-        try {
-            // KLP or later
-            sGetAllocationByteCount = Bitmap.class.getMethod("getAllocationByteCount");
-        } catch (NoSuchMethodException e) {
-        }
-    }
-
-    private final SparseArray<ArrayList<SoftReference<Bitmap>>> mRecycled8888 =
-            new SparseArray<ArrayList<SoftReference<Bitmap>>>();
-
-    public RecycleBitmapPool() {
-    }
-
-    public static int getSize(Bitmap bitmap) {
-        if (sGetAllocationByteCount != null) {
-            try {
-                return (Integer) sGetAllocationByteCount.invoke(bitmap);
-            } catch (IllegalArgumentException e) {
-                Log.e(TAG, "getAllocationByteCount() failed", e);
-            } catch (IllegalAccessException e) {
-                Log.e(TAG, "getAllocationByteCount() failed", e);
-            } catch (InvocationTargetException e) {
-                Log.e(TAG, "getAllocationByteCount() failed", e);
-            }
-            sGetAllocationByteCount = null;
-        }
-        return bitmap.getByteCount();
-    }
-
-    private static int getSize(int width, int height) {
-        if (width >= 2048 || height >= 2048) {
-            return 0;
-        }
-        return width * height * 4;
-    }
-
-    public void addRecycledBitmap(Bitmap bitmap) {
-        if (bitmap.isRecycled()) {
-            return;
-        }
-        Bitmap.Config config = bitmap.getConfig();
-        if (config != Bitmap.Config.ARGB_8888) {
-            return;
-        }
-        int key = getSize(bitmap);
-        if (key == 0) {
-            return;
-        }
-        synchronized (mRecycled8888) {
-            ArrayList<SoftReference<Bitmap>> list = mRecycled8888.get(key);
-            if (list == null) {
-                list = new ArrayList<SoftReference<Bitmap>>();
-                mRecycled8888.put(key, list);
-            }
-            list.add(new SoftReference<Bitmap>(bitmap));
-            if (DEBUG) {
-                Log.d(TAG, list.size() + " add bitmap " + bitmap.getWidth() + " "
-                        + bitmap.getHeight());
-            }
-        }
-    }
-
-    public Bitmap getRecycledBitmap(int width, int height) {
-        int key = getSize(width, height);
-        if (key == 0) {
-            return null;
-        }
-        synchronized (mRecycled8888) {
-            // for the new version with getAllocationByteCount(), we allow larger size
-            // to be reused for the bitmap,  otherwise we just looks for same size
-            Bitmap bitmap = getRecycledBitmap(mRecycled8888.get(key));
-            if (sGetAllocationByteCount == null || bitmap != null) {
-                return bitmap;
-            }
-            if (LARGER_BITMAP_ALLOWED) {
-                for (int i = 0, c = mRecycled8888.size(); i < c; i++) {
-                    int k = mRecycled8888.keyAt(i);
-                    if (k > key && k <= key * LARGER_BITMAP_ALLOWED_REUSE) {
-                        bitmap = getRecycledBitmap(mRecycled8888.valueAt(i));
-                        if (bitmap != null) {
-                            return bitmap;
-                        }
-                    }
-                }
-            }
-        }
-        if (DEBUG) {
-            Log.d(TAG, "not avaialbe for " + width + "," + height);
-        }
-        return null;
-    }
-
-    private static Bitmap getRecycledBitmap(ArrayList<SoftReference<Bitmap>> list) {
-        if (list != null && !list.isEmpty()) {
-            while (!list.isEmpty()) {
-                SoftReference<Bitmap> ref = list.remove(list.size() - 1);
-                Bitmap bitmap = ref.get();
-                if (bitmap != null && !bitmap.isRecycled()) {
-                    if (DEBUG) {
-                        Log.d(TAG, "reuse " + bitmap.getWidth() + " " + bitmap.getHeight());
-                    }
-                    return bitmap;
-                } else {
-                    if (DEBUG) {
-                        Log.d(TAG, " we lost SoftReference to bitmap");
-                    }
-                }
-            }
-        }
-        return null;
-    }
-}
diff --git a/car-apps-common/src/com/android/car/apps/common/RefcountBitmapDrawable.java b/car-apps-common/src/com/android/car/apps/common/RefcountBitmapDrawable.java
deleted file mode 100644
index 01a4bb1..0000000
--- a/car-apps-common/src/com/android/car/apps/common/RefcountBitmapDrawable.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.car.apps.common;
-
-import android.content.res.Resources;
-import android.graphics.Bitmap;
-import android.graphics.drawable.BitmapDrawable;
-
-/**
- * RefcountBitmapDrawable class
- * @hide
- */
-public class RefcountBitmapDrawable extends BitmapDrawable {
-
-    private RefcountObject<Bitmap> mRefcountObject;
-
-    /**
-     *  create initial drawable,  this will not increase the refcount
-     */
-    public RefcountBitmapDrawable(Resources res, RefcountObject<Bitmap> bitmap) {
-        super(res, bitmap.getObject());
-        mRefcountObject = bitmap;
-    }
-
-    /**
-     *  create the drawable from existing drawable, will not increase refcount
-     */
-    public RefcountBitmapDrawable(Resources res, RefcountBitmapDrawable drawable) {
-        this(res, drawable.getRefcountObject());
-    }
-
-    public RefcountObject<Bitmap> getRefcountObject() {
-        return mRefcountObject;
-    }
-}
