diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 5faf095..bc42835 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -344,6 +344,13 @@
                 <action android:name="android.bluetooth.IBluetoothAvrcpController" />
             </intent-filter>
         </service>
+        <provider android:process="@string/process"
+            android:name=".avrcpcontroller.AvrcpCoverArtProvider"
+            android:authorities="com.android.bluetooth.avrcpcontroller.AvrcpCoverArtProvider"
+            android:enabled="@bool/avrcp_controller_enable_cover_art"
+            android:grantUriPermissions="true"
+            android:exported="true">
+        </provider>
         <service
             android:process="@string/process"
             android:name = ".hid.HidHostService"
diff --git a/jni/com_android_bluetooth_avrcp_controller.cpp b/jni/com_android_bluetooth_avrcp_controller.cpp
index 818a38f..55a6af6 100755
--- a/jni/com_android_bluetooth_avrcp_controller.cpp
+++ b/jni/com_android_bluetooth_avrcp_controller.cpp
@@ -49,6 +49,7 @@
 static jmethodID method_handleAddressedPlayerChanged;
 static jmethodID method_handleNowPlayingContentChanged;
 static jmethodID method_onAvailablePlayerChanged;
+static jmethodID method_getRcPsm;
 
 static jclass class_AvrcpItem;
 static jclass class_AvrcpPlayer;
@@ -722,27 +723,50 @@
 
 static void btavrcp_available_player_changed_callback (
     const RawAddress& bd_addr) {
-    ALOGI("%s", __func__);
-
-    std::shared_lock<std::shared_timed_mutex> lock(sCallbacks_mutex);
-
-    CallbackEnv sCallbackEnv(__func__);
-    if (!sCallbacksObj) {
-        ALOGE("%s: sCallbacksObj is null", __func__);
-        return;
-    }
-    if (!sCallbackEnv.valid()) return;
-    ScopedLocalRef<jbyteArray> addr(
-        sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
-    if (!addr.get()) {
-      ALOGE("%s: Failed to allocate a new byte array", __func__);
+  ALOGI("%s", __func__);
+  std::shared_lock<std::shared_timed_mutex> lock(sCallbacks_mutex);
+  CallbackEnv sCallbackEnv(__func__);
+  if (!sCallbacksObj) {
+      ALOGE("%s: sCallbacksObj is null", __func__);
       return;
-    }
+  }
+  if (!sCallbackEnv.valid()) return;
 
-    sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress),
-                                     (jbyte*)&bd_addr);
-    sCallbackEnv->CallVoidMethod(
-        sCallbacksObj, method_onAvailablePlayerChanged, addr.get());
+  ScopedLocalRef<jbyteArray> addr(
+      sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
+  if (!addr.get()) {
+    ALOGE("%s: Failed to allocate a new byte array", __func__);
+    return;
+  }
+
+  sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress),
+                                    (jbyte*)&bd_addr);
+  sCallbackEnv->CallVoidMethod(
+      sCallbacksObj, method_onAvailablePlayerChanged, addr.get());
+}
+
+static void btavrcp_get_rcpsm_callback(const RawAddress& bd_addr,
+                                       uint16_t psm) {
+  ALOGE("%s -> psm received of %d", __func__, psm);
+  std::shared_lock<std::shared_timed_mutex> lock(sCallbacks_mutex);
+  CallbackEnv sCallbackEnv(__func__);
+  if (!sCallbacksObj) {
+    ALOGE("%s: sCallbacksObj is null", __func__);
+    return;
+  }
+  if (!sCallbackEnv.valid()) return;
+
+  ScopedLocalRef<jbyteArray> addr(
+      sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
+  if (!addr.get()) {
+    ALOGE("%s: Failed to allocate a new byte array", __func__);
+    return;
+  }
+
+  sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress),
+                                   (jbyte*)&bd_addr.address);
+  sCallbackEnv->CallVoidMethod(sCallbacksObj, method_getRcPsm, addr.get(),
+                               (jint)psm);
 }
 
 static btrc_ctrl_callbacks_t sBluetoothAvrcpCallbacks = {
@@ -765,7 +789,8 @@
     btavrcp_set_addressed_player_callback,
     btavrcp_addressed_player_changed_callback,
     btavrcp_now_playing_content_changed_callback,
-    btavrcp_available_player_changed_callback};
+    btavrcp_available_player_changed_callback,
+    btavrcp_get_rcpsm_callback};
 
 static void classInitNative(JNIEnv* env, jclass clazz) {
   method_handlePassthroughRsp =
@@ -779,6 +804,8 @@
 
   method_getRcFeatures = env->GetMethodID(clazz, "getRcFeatures", "([BI)V");
 
+  method_getRcPsm = env->GetMethodID(clazz, "getRcPsm", "([BI)V");
+
   method_setplayerappsettingrsp =
       env->GetMethodID(clazz, "setPlayerAppSettingRsp", "([BB)V");
 
diff --git a/res/values/config.xml b/res/values/config.xml
index 711993e..376d996 100644
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -72,6 +72,9 @@
     <!-- If true, device requests audio focus and start avrcp updates on source start or play -->
     <bool name="a2dp_sink_automatically_request_audio_focus">false</bool>
 
+    <!-- For enabling the AVRCP Controller Cover Artwork feature -->
+    <bool name="avrcp_controller_enable_cover_art">false</bool>
+
     <!-- For enabling the hfp client connection service -->
     <bool name="hfp_client_connection_service_enabled">false</bool>
 
diff --git a/src/com/android/bluetooth/avrcpcontroller/AvrcpBipClient.java b/src/com/android/bluetooth/avrcpcontroller/AvrcpBipClient.java
new file mode 100644
index 0000000..c53954b
--- /dev/null
+++ b/src/com/android/bluetooth/avrcpcontroller/AvrcpBipClient.java
@@ -0,0 +1,403 @@
+/*
+ * Copyright (C) 2019 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.bluetooth.avrcpcontroller;
+
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothProfile;
+import android.bluetooth.BluetoothSocket;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.Looper;
+import android.os.Message;
+import android.util.Log;
+
+import com.android.bluetooth.BluetoothObexTransport;
+
+import java.io.IOException;
+import java.lang.ref.WeakReference;
+
+import javax.obex.ClientSession;
+import javax.obex.HeaderSet;
+import javax.obex.ResponseCodes;
+
+/**
+ * A client to a remote device's BIP Image Pull Server, as defined by a PSM passed in at
+ * construction time.
+ *
+ * Once the client connection is established you can use this client to get image properties and
+ * download images. The connection to the server is held open to service multiple requests.
+ *
+ * Client is good for one connection lifecycle. Please call shutdown() to clean up safely. Once a
+ * disconnection has occurred, please create a new client.
+ */
+public class AvrcpBipClient {
+    private static final String TAG = "AvrcpBipClient";
+    private static final boolean DBG = Log.isLoggable(TAG, Log.DEBUG);
+
+    // AVRCP Controller BIP Image Initiator/Cover Art UUID - AVRCP 1.6 Section 5.14.2.1
+    private static final byte[] BLUETOOTH_UUID_AVRCP_COVER_ART = new byte[] {
+        (byte) 0x71,
+        (byte) 0x63,
+        (byte) 0xDD,
+        (byte) 0x54,
+        (byte) 0x4A,
+        (byte) 0x7E,
+        (byte) 0x11,
+        (byte) 0xE2,
+        (byte) 0xB4,
+        (byte) 0x7C,
+        (byte) 0x00,
+        (byte) 0x50,
+        (byte) 0xC2,
+        (byte) 0x49,
+        (byte) 0x00,
+        (byte) 0x48
+    };
+
+    private static final int CONNECT = 0;
+    private static final int DISCONNECT = 1;
+    private static final int REQUEST = 2;
+
+    private final Handler mHandler;
+    private final HandlerThread mThread;
+
+    private final BluetoothDevice mDevice;
+    private final int mPsm;
+    private int mState = BluetoothProfile.STATE_DISCONNECTED;
+
+    private BluetoothSocket mSocket;
+    private BluetoothObexTransport mTransport;
+    private ClientSession mSession;
+
+    private final Callback mCallback;
+
+    /**
+     * Callback object used to be notified of when a request has been completed.
+     */
+    interface Callback {
+
+        /**
+         * Notify of a connection state change in the client
+         *
+         * @param oldState The old state of the client
+         * @param newState The new state of the client
+         */
+        void onConnectionStateChanged(int oldState, int newState);
+
+        /**
+         * Notify of a get image properties completing
+         *
+         * @param status A status code to indicate a success or error
+         * @param properties The BipImageProperties object returned if successful, null otherwise
+         */
+        void onGetImagePropertiesComplete(int status, String imageHandle,
+                BipImageProperties properties);
+
+        /**
+         * Notify of a get image operation completing
+         *
+         * @param status A status code of the request. success or error
+         * @param image The BipImage object returned if successful, null otherwise
+         */
+        void onGetImageComplete(int status, String imageHandle, BipImage image);
+    }
+
+    /**
+     * Creates a BIP image pull client and connects to a remote device's BIP image push server.
+     */
+    public AvrcpBipClient(BluetoothDevice remoteDevice, int psm, Callback callback) {
+        if (remoteDevice == null) {
+            throw new NullPointerException("Remote device is null");
+        }
+        if (callback == null) {
+            throw new NullPointerException("Callback is null");
+        }
+
+        mDevice = remoteDevice;
+        mPsm = psm;
+        mCallback = callback;
+
+        mThread = new HandlerThread("AvrcpBipClient");
+        mThread.start();
+
+        Looper looper = mThread.getLooper();
+
+        mHandler = new AvrcpBipClientHandler(looper, this);
+        mHandler.obtainMessage(CONNECT).sendToTarget();
+    }
+
+    /**
+     * Safely disconnects the client from the server
+     */
+    public void shutdown() {
+        debug("Shutdown client");
+        try {
+            mHandler.obtainMessage(DISCONNECT).sendToTarget();
+        } catch (IllegalStateException e) {
+            // Means we haven't been started or we're already stopped. Doing this makes this call
+            // always safe no matter the state.
+            return;
+        }
+        mThread.quitSafely();
+    }
+
+    /**
+     * Determines if this client is connected to the server
+     *
+     * @return True if connected, False otherwise
+     */
+    public synchronized int getState() {
+        return mState;
+    }
+
+    /**
+     * Determines if this client is connected to the server
+     *
+     * @return True if connected, False otherwise
+     */
+    public boolean isConnected() {
+        return getState() == BluetoothProfile.STATE_CONNECTED;
+    }
+
+    /**
+     * Retrieve the image properties associated with the given imageHandle
+     */
+    public boolean getImageProperties(String imageHandle) {
+        RequestGetImageProperties request =  new RequestGetImageProperties(imageHandle);
+        boolean status = mHandler.sendMessage(mHandler.obtainMessage(REQUEST, request));
+        if (!status) {
+            error("Adding messages failed, connection state: " + isConnected());
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * Download the image object associated with the given imageHandle
+     */
+    public boolean getImage(String imageHandle, BipImageDescriptor descriptor) {
+        RequestGetImage request =  new RequestGetImage(imageHandle, descriptor);
+        boolean status = mHandler.sendMessage(mHandler.obtainMessage(REQUEST, request));
+        if (!status) {
+            error("Adding messages failed, connection state: " + isConnected());
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * Update our client's connection state and notify of the new status
+     */
+    private void setConnectionState(int state) {
+        int oldState = -1;
+        synchronized (this) {
+            oldState = mState;
+            mState = state;
+        }
+        if (oldState != state)  {
+            mCallback.onConnectionStateChanged(oldState, mState);
+        }
+    }
+
+    /**
+     * Connects to the remote device's BIP Image Pull server
+     */
+    private synchronized void connect() {
+        debug("Connect using psm: " + mPsm);
+        if (isConnected()) {
+            warn("Already connected");
+            return;
+        }
+
+        try {
+            setConnectionState(BluetoothProfile.STATE_CONNECTING);
+
+            mSocket = mDevice.createL2capSocket(mPsm);
+            mSocket.connect();
+
+            mTransport = new BluetoothObexTransport(mSocket);
+            mSession = new ClientSession(mTransport);
+
+            HeaderSet headerSet = new HeaderSet();
+            headerSet.setHeader(HeaderSet.TARGET, BLUETOOTH_UUID_AVRCP_COVER_ART);
+
+            headerSet = mSession.connect(headerSet);
+            int responseCode = headerSet.getResponseCode();
+            if (responseCode == ResponseCodes.OBEX_HTTP_OK) {
+                setConnectionState(BluetoothProfile.STATE_CONNECTED);
+            } else {
+                error("Error connecting, code: " + responseCode);
+                disconnect();
+            }
+            debug("Connection established");
+
+        } catch (IOException e) {
+            error("Exception while connecting to AVRCP BIP server", e);
+            disconnect();
+        }
+    }
+
+    /**
+     * Permanently disconnects this client from the remote device's BIP server and notifies of the
+     * new connection status.
+     *
+     */
+    private synchronized void disconnect() {
+        if (mSession != null) {
+            setConnectionState(BluetoothProfile.STATE_DISCONNECTING);
+
+            try {
+                mSession.disconnect(null);
+            } catch (IOException e) {
+                error("Exception while disconnecting from AVRCP BIP server: " + e.toString());
+            }
+
+            try {
+                mSession.close();
+            } catch (IOException e) {
+                error("Exception while closing AVRCP BIP session: " + e.toString());
+            }
+
+            mSession = null;
+        }
+        setConnectionState(BluetoothProfile.STATE_DISCONNECTED);
+    }
+
+    private void executeRequest(BipRequest request) {
+        if (!isConnected()) {
+            error("Cannot execute request " + request.toString()
+                    + ", we're not connected");
+            notifyCaller(request);
+            return;
+        }
+
+        try {
+            request.execute(mSession);
+            notifyCaller(request);
+            debug("Completed request - " + request.toString());
+        } catch (IOException e) {
+            error("Request failed: " + request.toString());
+            notifyCaller(request);
+            disconnect();
+        }
+    }
+
+    private void notifyCaller(BipRequest request) {
+        int type = request.getType();
+        int responseCode = request.getResponseCode();
+        String imageHandle = null;
+
+        debug("Notifying caller of request complete - " + request.toString());
+        switch (type) {
+            case BipRequest.TYPE_GET_IMAGE_PROPERTIES:
+                imageHandle = ((RequestGetImageProperties) request).getImageHandle();
+                BipImageProperties properties =
+                        ((RequestGetImageProperties) request).getImageProperties();
+                mCallback.onGetImagePropertiesComplete(responseCode, imageHandle, properties);
+                break;
+            case BipRequest.TYPE_GET_IMAGE:
+                imageHandle = ((RequestGetImage) request).getImageHandle();
+                BipImage image = ((RequestGetImage) request).getImage();
+                mCallback.onGetImageComplete(responseCode, imageHandle, image); // TODO: add handle
+                break;
+        }
+    }
+
+    /**
+     * Handles this AVRCP BIP Image Pull Client's requests
+     */
+    private static class AvrcpBipClientHandler extends Handler {
+        WeakReference<AvrcpBipClient> mInst;
+
+        AvrcpBipClientHandler(Looper looper, AvrcpBipClient inst) {
+            super(looper);
+            mInst = new WeakReference<>(inst);
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            AvrcpBipClient inst = mInst.get();
+            switch (msg.what) {
+                case CONNECT:
+                    if (!inst.isConnected()) {
+                        inst.connect();
+                    }
+                    break;
+
+                case DISCONNECT:
+                    if (inst.isConnected()) {
+                        inst.disconnect();
+                    }
+                    break;
+
+                case REQUEST:
+                    if (inst.isConnected()) {
+                        inst.executeRequest((BipRequest) msg.obj);
+                    }
+                    break;
+            }
+        }
+    }
+
+    private String getStateName() {
+        int state = getState();
+        switch (state) {
+            case BluetoothProfile.STATE_DISCONNECTED:
+                return "Disconnected";
+            case BluetoothProfile.STATE_CONNECTING:
+                return "Connecting";
+            case BluetoothProfile.STATE_CONNECTED:
+                return "Connected";
+            case BluetoothProfile.STATE_DISCONNECTING:
+                return "Disconnecting";
+        }
+        return "Unknown";
+    }
+
+    @Override
+    public String toString() {
+        return "<AvrcpBipClient" + " device=" + mDevice.getAddress() + " psm=" + mPsm
+                + " state=" + getStateName() + ">";
+    }
+
+    /**
+     * Print to debug if debug is enabled for this class
+     */
+    private void debug(String msg) {
+        if (DBG) {
+            Log.d(TAG, "[" + mDevice.getAddress() + "] " + msg);
+        }
+    }
+
+    /**
+     * Print to warn
+     */
+    private void warn(String msg) {
+        Log.w(TAG, "[" + mDevice.getAddress() + "] " + msg);
+    }
+
+    /**
+     * Print to error
+     */
+    private void error(String msg) {
+        Log.e(TAG, "[" + mDevice.getAddress() + "] " + msg);
+    }
+
+    private void error(String msg, Throwable e) {
+        Log.e(TAG, "[" + mDevice.getAddress() + "] " + msg, e);
+    }
+}
diff --git a/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerService.java b/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerService.java
index 059feeb..a58e4d6 100755
--- a/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerService.java
+++ b/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerService.java
@@ -26,6 +26,7 @@
 import android.support.v4.media.session.PlaybackStateCompat;
 import android.util.Log;
 
+import com.android.bluetooth.R;
 import com.android.bluetooth.Utils;
 import com.android.bluetooth.btservice.ProfileService;
 
@@ -94,6 +95,28 @@
     protected Map<BluetoothDevice, AvrcpControllerStateMachine> mDeviceStateMap =
             new ConcurrentHashMap<>(1);
 
+    private boolean mCoverArtEnabled;
+    protected AvrcpCoverArtManager mCoverArtManager;
+
+    private class ImageDownloadCallback implements AvrcpCoverArtManager.Callback {
+        @Override
+        public void onImageDownloadComplete(BluetoothDevice device,
+                AvrcpCoverArtManager.DownloadEvent event) {
+            if (DBG) {
+                Log.d(TAG, "Image downloaded [device: " + device + ", handle: " + event.getHandle()
+                        + ", uri: " + event.getUri());
+            }
+            AvrcpControllerStateMachine stateMachine = getStateMachine(device);
+            if (stateMachine == null) {
+                Log.e(TAG, "No state machine found for device " + device);
+                mCoverArtManager.removeImage(device, event.getHandle());
+                return;
+            }
+            stateMachine.sendMessage(AvrcpControllerStateMachine.MESSAGE_PROCESS_IMAGE_DOWNLOADED,
+                    event);
+        }
+    }
+
     static {
         classInitNative();
     }
@@ -106,6 +129,10 @@
     @Override
     protected boolean start() {
         initNative();
+        mCoverArtEnabled = getResources().getBoolean(R.bool.avrcp_controller_enable_cover_art);
+        if (mCoverArtEnabled) {
+            mCoverArtManager = new AvrcpCoverArtManager(this, new ImageDownloadCallback());
+        }
         sBrowseTree = new BrowseTree(null);
         sService = this;
 
@@ -125,6 +152,8 @@
 
         sService = null;
         sBrowseTree = null;
+        mCoverArtManager.cleanup();
+        mCoverArtManager = null;
         return true;
     }
 
@@ -324,6 +353,17 @@
         /* Do Nothing. */
     }
 
+    // Called by JNI to notify Avrcp of a remote device's Cover Art PSM
+    private void getRcPsm(byte[] address, int psm) {
+        BluetoothDevice device = mAdapter.getRemoteDevice(address);
+        if (DBG) Log.d(TAG, "getRcPsm(device=" + device + ", psm=" + psm + ")");
+        AvrcpControllerStateMachine stateMachine = getOrCreateStateMachine(device);
+        if (stateMachine != null) {
+            stateMachine.sendMessage(
+                    AvrcpControllerStateMachine.MESSAGE_PROCESS_RECEIVED_COVER_ART_PSM, psm);
+        }
+    }
+
     // Called by JNI
     private void setPlayerAppSettingRsp(byte[] address, byte accepted) {
         /* Do Nothing. */
@@ -371,7 +411,6 @@
             aib.setItemType(AvrcpItem.TYPE_MEDIA);
             aib.setUuid(UUID.randomUUID().toString());
             AvrcpItem item = aib.build();
-
             stateMachine.sendMessage(AvrcpControllerStateMachine.MESSAGE_PROCESS_TRACK_CHANGED,
                     item);
         }
@@ -492,7 +531,6 @@
         }
     }
 
-
     void handleGetPlayerItemsRsp(byte[] address, AvrcpPlayer[] items) {
         if (DBG) {
             Log.d(TAG, "handleGetFolderItemsRsp called with " + items.length + " items.");
@@ -529,7 +567,6 @@
         aib.setUuid(UUID.randomUUID().toString());
         aib.setPlayable(true);
         AvrcpItem item = aib.build();
-
         return item;
     }
 
@@ -689,6 +726,10 @@
         return stateMachine;
     }
 
+    protected AvrcpCoverArtManager getCoverArtManager() {
+        return mCoverArtManager;
+    }
+
     List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
         if (DBG) Log.d(TAG, "getDevicesMatchingConnectionStates" + Arrays.toString(states));
         List<BluetoothDevice> deviceList = new ArrayList<>();
@@ -725,6 +766,11 @@
             stateMachine.dump(sb);
         }
         sb.append("\n  sBrowseTree: " + sBrowseTree.toString());
+
+        sb.append("\n  Cover Artwork Enabled: " + (mCoverArtEnabled ? "True" : "False"));
+        if (mCoverArtManager != null) {
+            sb.append("\n  " + mCoverArtManager.toString());
+        }
     }
 
     /*JNI*/
diff --git a/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerStateMachine.java b/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerStateMachine.java
index a133d72..df92ad7 100755
--- a/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerStateMachine.java
+++ b/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerStateMachine.java
@@ -22,6 +22,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.media.AudioManager;
+import android.net.Uri;
 import android.os.Bundle;
 import android.os.Message;
 import android.support.v4.media.session.MediaSessionCompat;
@@ -57,6 +58,7 @@
     //100->199 Internal Events
     protected static final int CLEANUP = 100;
     private static final int CONNECT_TIMEOUT = 101;
+    static final int MESSAGE_INTERNAL_ABS_VOL_TIMEOUT = 102;
 
     //200->299 Events from Native
     static final int STACK_EVENT = 200;
@@ -79,6 +81,7 @@
     static final int MESSAGE_PROCESS_SUPPORTED_APPLICATION_SETTINGS = 217;
     static final int MESSAGE_PROCESS_CURRENT_APPLICATION_SETTINGS = 218;
     static final int MESSAGE_PROCESS_AVAILABLE_PLAYER_CHANGED = 219;
+    static final int MESSAGE_PROCESS_RECEIVED_COVER_ART_PSM = 220;
 
     //300->399 Events for Browsing
     static final int MESSAGE_GET_FOLDER_ITEMS = 300;
@@ -87,7 +90,8 @@
     static final int MSG_AVRCP_SET_SHUFFLE = 303;
     static final int MSG_AVRCP_SET_REPEAT = 304;
 
-    static final int MESSAGE_INTERNAL_ABS_VOL_TIMEOUT = 404;
+    //400->499 Events for Cover Artwork
+    static final int MESSAGE_PROCESS_IMAGE_DOWNLOADED = 400;
 
     /*
      * Base value for absolute volume from JNI
@@ -107,6 +111,8 @@
     protected final BluetoothDevice mDevice;
     protected final byte[] mDeviceAddress;
     protected final AvrcpControllerService mService;
+    protected int mCoverArtPsm;
+    protected final AvrcpCoverArtManager mCoverArtManager;
     protected final Disconnected mDisconnected;
     protected final Connecting mConnecting;
     protected final Connected mConnected;
@@ -135,6 +141,8 @@
         mDevice = device;
         mDeviceAddress = Utils.getByteAddress(mDevice);
         mService = service;
+        mCoverArtPsm = 0;
+        mCoverArtManager = service.getCoverArtManager();
         logD(device.toString());
 
         mBrowseTree = new BrowseTree(mDevice);
@@ -278,6 +286,22 @@
         mBrowsingConnected = false;
     }
 
+    synchronized void connectCoverArt() {
+        // Called from "connected" state, which assumes either control or browse is connected
+        if (mCoverArtManager != null && mCoverArtPsm != 0) {
+            logD("Attempting to connect to AVRCP BIP, psm: " + mCoverArtPsm);
+            mCoverArtManager.connect(mDevice, /* psm */ mCoverArtPsm);
+        }
+    }
+
+    synchronized void disconnectCoverArt() {
+        // Safe to call even if we're not connected
+        if (mCoverArtManager != null) {
+            logD("Disconnect BIP cover artwork");
+            mCoverArtManager.disconnect(mDevice);
+        }
+    }
+
     private void notifyChanged(BrowseTree.BrowseNode node) {
         BluetoothMediaBrowserService.notifyChanged(node);
     }
@@ -315,6 +339,9 @@
         @Override
         public boolean processMessage(Message message) {
             switch (message.what) {
+                case MESSAGE_PROCESS_RECEIVED_COVER_ART_PSM:
+                    mCoverArtPsm = message.arg1;
+                    break;
                 case CONNECT:
                     logD("Connect");
                     transitionTo(mConnecting);
@@ -348,6 +375,7 @@
                 BluetoothMediaBrowserService.addressedPlayerChanged(mSessionCallbacks);
                 BluetoothMediaBrowserService.notifyChanged(mAddressedPlayer.getPlaybackState());
                 broadcastConnectionStateChanged(BluetoothProfile.STATE_CONNECTED);
+                connectCoverArt(); // only works if we have a valid PSM
             } else {
                 logD("ReEnteringConnected");
             }
@@ -396,6 +424,7 @@
 
                 case MESSAGE_PROCESS_TRACK_CHANGED:
                     AvrcpItem track = (AvrcpItem) msg.obj;
+                    downloadImageIfNeeded(track);
                     mAddressedPlayer.updateCurrentTrack(track);
                     if (isActive()) {
                         BluetoothMediaBrowserService.trackChanged(track);
@@ -458,6 +487,31 @@
                     processAvailablePlayerChanged();
                     return true;
 
+                case MESSAGE_PROCESS_RECEIVED_COVER_ART_PSM:
+                    mCoverArtPsm = msg.arg1;
+                    connectCoverArt();
+                    return true;
+
+                case MESSAGE_PROCESS_IMAGE_DOWNLOADED:
+                    AvrcpCoverArtManager.DownloadEvent event =
+                            (AvrcpCoverArtManager.DownloadEvent) msg.obj;
+                    String handle = event.getHandle();
+                    Uri uri = event.getUri();
+                    logD("Received image for " + handle + " at " + uri.toString());
+
+                    // Let the addressed player know we got an image so it can see if the current
+                    // track now has cover artwork
+                    boolean addedArtwork = mAddressedPlayer.notifyImageDownload(handle, uri);
+                    if (addedArtwork) {
+                        BluetoothMediaBrowserService.trackChanged(
+                                mAddressedPlayer.getCurrentTrack());
+                    }
+
+                    // Let the browse tree know of the newly downloaded image so it can attach it to
+                    // all the items that need it
+                    mBrowseTree.notifyImageDownload(handle, uri);
+                    return true;
+
                 case DISCONNECT:
                     transitionTo(mDisconnecting);
                     return true;
@@ -581,6 +635,11 @@
                     logD("GetFolderItems: End " + endIndicator
                             + " received " + folderList.size());
 
+                    // Queue up image download if the item has an image and we don't have it yet
+                    for (AvrcpItem track : folderList) {
+                        downloadImageIfNeeded(track);
+                    }
+
                     // Always update the node so that the user does not wait forever
                     // for the list to populate.
                     int newSize = mBrowseNode.addChildren(folderList);
@@ -779,6 +838,7 @@
     protected class Disconnecting extends State {
         @Override
         public void enter() {
+            disconnectCoverArt();
             onBrowsingDisconnected();
             if (isActive()) {
                 sActiveDevice = null;
@@ -846,6 +906,20 @@
         return newIndex;
     }
 
+    private void downloadImageIfNeeded(AvrcpItem track) {
+        if (mCoverArtManager == null) return;
+        String handle = track.getCoverArtHandle();
+        Uri imageUri = null;
+        if (handle != null) {
+            imageUri = mCoverArtManager.getImageUri(mDevice, handle);
+            if (imageUri != null) {
+                track.setCoverArtLocation(imageUri);
+            } else {
+                mCoverArtManager.downloadImage(mDevice, handle);
+            }
+        }
+    }
+
     MediaSessionCompat.Callback mSessionCallbacks = new MediaSessionCompat.Callback() {
         @Override
         public void onPlay() {
diff --git a/src/com/android/bluetooth/avrcpcontroller/AvrcpCoverArtManager.java b/src/com/android/bluetooth/avrcpcontroller/AvrcpCoverArtManager.java
new file mode 100644
index 0000000..72efdfb
--- /dev/null
+++ b/src/com/android/bluetooth/avrcpcontroller/AvrcpCoverArtManager.java
@@ -0,0 +1,320 @@
+/*
+ * Copyright (C) 2019 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.bluetooth.avrcpcontroller;
+
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothProfile;
+import android.content.Context;
+import android.net.Uri;
+import android.util.Log;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import javax.obex.ResponseCodes;
+
+/**
+ * Manager of all AVRCP Controller connections to remote devices' BIP servers for retrieving cover
+ * art.
+ *
+ * When given an image handle and device, this manager will negotiate the downloaded image
+ * properties, download the image, and place it into a Content Provider for others to retrieve from
+ */
+public class AvrcpCoverArtManager {
+    private static final String TAG = "AvrcpCoverArtManager";
+    private static final boolean DBG = Log.isLoggable(TAG, Log.DEBUG);
+
+    private final Context mContext;
+    protected final Map<BluetoothDevice, AvrcpBipClient> mClients = new ConcurrentHashMap<>(1);
+    private final AvrcpCoverArtStorage mCoverArtStorage;
+    private final Callback mCallback;
+
+    /**
+     * An object representing an image download event. Contains the information necessary to
+     * retrieve the image from storage.
+     */
+    public class DownloadEvent {
+        final String mImageHandle;
+        final Uri mUri;
+        public DownloadEvent(String handle, Uri uri) {
+            mImageHandle = handle;
+            mUri = uri;
+        }
+        public String getHandle() {
+            return mImageHandle;
+        }
+        public Uri getUri() {
+            return mUri;
+        }
+    }
+
+    interface Callback {
+        /**
+         * Notify of a get image download completing
+         *
+         * @param device The device the image handle belongs to
+         * @param imageHandle The handle of the requested image
+         * @param uri The Uri that the image is available at in storage
+         */
+        void onImageDownloadComplete(BluetoothDevice device, DownloadEvent event);
+    }
+
+    public AvrcpCoverArtManager(Context context, Callback callback) {
+        mContext = context;
+        mCoverArtStorage = new AvrcpCoverArtStorage(mContext);
+        mCallback = callback;
+    }
+
+    /**
+     * Create a client and connect to a remote device's BIP Image Pull Server
+     *
+     * @param device The remote Bluetooth device you wish to connect to
+     * @param psm The Protocol Service Multiplexer that the remote device is hosting the server on
+     * @return True if the connection is successfully queued, False otherwise.
+     */
+    public synchronized boolean connect(BluetoothDevice device, int psm) {
+        debug("Connect " + device.getAddress() + ", psm: " + psm);
+        if (mClients.containsKey(device)) return false;
+        AvrcpBipClient client = new AvrcpBipClient(device, psm, new BipClientCallback(device));
+        mClients.put(device, client);
+        return true;
+    }
+
+    /**
+     * Disconnect from a remote device's BIP Image Pull Server
+     *
+     * @param device The remote Bluetooth device you wish to connect to
+     * @return True if the connection is successfully queued, False otherwise.
+     */
+    public synchronized boolean disconnect(BluetoothDevice device) {
+        debug("Disconnect " + device.getAddress());
+        if (!mClients.containsKey(device)) {
+            warn("No client for " + device.getAddress());
+            return false;
+        }
+        AvrcpBipClient client = getClient(device);
+        client.shutdown();
+        mClients.remove(device);
+        mCoverArtStorage.removeImagesForDevice(device);
+        return true;
+    }
+
+    /**
+     * Cleanup all cover art related resources
+     *
+     * Please call when you've committed to shutting down the service.
+     */
+    public synchronized void cleanup() {
+        debug("Clean up and shutdown");
+        for (BluetoothDevice device : mClients.keySet()) {
+            disconnect(device);
+        }
+    }
+
+    /**
+     * Get the client connection state for a particular device's BIP Client
+     *
+     * @param device The Bluetooth device you want connection status for
+     * @return Connection status, based on BluetoothProfile.STATE_* constants
+     */
+    public int getState(BluetoothDevice device) {
+        AvrcpBipClient client = mClients.get(device);
+        if (client == null) return BluetoothProfile.STATE_DISCONNECTED;
+        return client.getState();
+    }
+
+    /**
+     * Get the Uri of an image if it has already been downloaded.
+     *
+     * @param device The remote Bluetooth device you wish to get an image for
+     * @param imageHandle The handle associated with the image you want
+     * @return A Uri the image can be found at, null if it does not exist
+     */
+    public Uri getImageUri(BluetoothDevice device, String imageHandle) {
+        if (mCoverArtStorage.doesImageExist(device, imageHandle)) {
+            return AvrcpCoverArtProvider.getImageUri(device, imageHandle);
+        }
+        return null;
+    }
+
+    /**
+     * Download an image from a remote device and make it findable via the given uri
+     *
+     * Downloading happens in three steps:
+     *   1) Get the available image formats by requesting the Image Properties
+     *   2) Determine the specific format we want the image in and turn it into an image descriptor
+     *   3) Get the image using the chosen descriptor
+     *
+     * Getting image properties and the image are both asynchronous in nature.
+     *
+     * @param device The remote Bluetooth device you wish to download from
+     * @param imageHandle The handle associated with the image you wish to download
+     * @return A Uri that will be assign to the image once the download is complete
+     */
+    public Uri downloadImage(BluetoothDevice device, String imageHandle) {
+        debug("Download Image - device: " + device.getAddress() + ", Handle: " + imageHandle);
+        AvrcpBipClient client = getClient(device);
+        if (client == null) {
+            error("Cannot download an image. No client is available.");
+            return null;
+        }
+
+        // Check to see if we have the image already. No need to download it if we do have it.
+        if (mCoverArtStorage.doesImageExist(device, imageHandle)) {
+            debug("Image is already downloaded");
+            return AvrcpCoverArtProvider.getImageUri(device, imageHandle);
+        }
+
+        // Getting image properties will return via the callback created when connecting, which
+        // invokes the download image function after we're returned the properties. If we already
+        // have the image, GetImageProperties returns true but does not start a download.
+        boolean status = client.getImageProperties(imageHandle);
+        if (!status) return null;
+
+        // Return the Uri that the caller should use to retrieve the image
+        return AvrcpCoverArtProvider.getImageUri(device, imageHandle);
+    }
+
+    /**
+     * Remote a specific downloaded image if it exists
+     *
+     * @param device The remote Bluetooth device associated with the image
+     * @param imageHandle The handle associated with the image you wish to remove
+     */
+    public void removeImage(BluetoothDevice device, String imageHandle) {
+        mCoverArtStorage.removeImage(device, imageHandle);
+    }
+
+    /**
+     * Get a device's BIP client if it exists
+     *
+     * @param device The device you want the client for
+     * @return The AvrcpBipClient object associated with the device, or null if it doesn't exist
+     */
+    private AvrcpBipClient getClient(BluetoothDevice device) {
+        return mClients.get(device);
+    }
+
+    /**
+     * Determines our preferred download descriptor from the list of available image download
+     * formats presented in the image properties object.
+     *
+     * Our goal is ensure the image arrives in a format Android can consume and to minimize transfer
+     * size if possible.
+     *
+     * @param properties The set of available formats and image is downloadable in
+     * @return A descriptor containing the desirable download format
+     */
+    private BipImageDescriptor determineImageDescriptor(BipImageProperties properties) {
+        // AVRCP 1.6.2 defined "thumbnail" size is guaranteed so we'll do that for now
+        BipImageDescriptor.Builder builder = new BipImageDescriptor.Builder();
+        builder.setEncoding(BipEncoding.JPEG);
+        builder.setFixedDimensions(200, 200);
+        return builder.build();
+    }
+
+    /**
+     * Callback for facilitating image download
+     */
+    class BipClientCallback implements AvrcpBipClient.Callback {
+        final BluetoothDevice mDevice;
+
+        BipClientCallback(BluetoothDevice device) {
+            mDevice = device;
+        }
+
+        @Override
+        public void onConnectionStateChanged(int oldState, int newState) {
+            debug(mDevice.getAddress() + ": " + oldState + " -> " + newState);
+            if (newState == BluetoothProfile.STATE_DISCONNECTED) {
+                disconnect(mDevice);
+            }
+        }
+
+        @Override
+        public void onGetImagePropertiesComplete(int status, String imageHandle,
+                BipImageProperties properties) {
+            if (status != ResponseCodes.OBEX_HTTP_OK || properties == null) {
+                warn(mDevice.getAddress() + ": GetImageProperties() failed - Handle: " + imageHandle
+                        + ", Code: " + status);
+                return;
+            }
+            BipImageDescriptor descriptor = determineImageDescriptor(properties);
+            debug(mDevice.getAddress() + ": Download image - handle='" + imageHandle + "'");
+
+            AvrcpBipClient client = getClient(mDevice);
+            if (client == null) {
+                warn(mDevice.getAddress() + ": Could not getImage() for " + imageHandle
+                        + " because client has disconnected.");
+                return;
+            }
+            client.getImage(imageHandle, descriptor);
+        }
+
+        @Override
+        public void onGetImageComplete(int status, String imageHandle, BipImage image) {
+            if (status != ResponseCodes.OBEX_HTTP_OK) {
+                warn(mDevice.getAddress() + ": GetImage() failed - Handle: " + imageHandle
+                        + ", Code: " + status);
+                return;
+            }
+            debug(mDevice.getAddress() + ": Received image data for handle: " + imageHandle
+                    + ", image: " + image);
+            Uri uri = mCoverArtStorage.addImage(mDevice, imageHandle, image.getImage());
+            if (uri == null) {
+                error("Could not store downloaded image");
+                return;
+            }
+            DownloadEvent event = new DownloadEvent(imageHandle, uri);
+            if (mCallback != null) mCallback.onImageDownloadComplete(mDevice, event);
+        }
+    }
+
+    @Override
+    public String toString() {
+        String s = "CoverArtManager:\n";
+        for (BluetoothDevice device : mClients.keySet()) {
+            AvrcpBipClient client = getClient(device);
+            s += "    " + client.toString() + "\n";
+        }
+        s += "  " + mCoverArtStorage.toString();
+        return s;
+    }
+
+    /**
+     * Print to debug if debug is enabled for this class
+     */
+    private void debug(String msg) {
+        if (DBG) {
+            Log.d(TAG, msg);
+        }
+    }
+
+    /**
+     * Print to warn
+     */
+    private void warn(String msg) {
+        Log.w(TAG, msg);
+    }
+
+    /**
+     * Print to error
+     */
+    private void error(String msg) {
+        Log.e(TAG, msg);
+    }
+}
diff --git a/src/com/android/bluetooth/avrcpcontroller/AvrcpCoverArtProvider.java b/src/com/android/bluetooth/avrcpcontroller/AvrcpCoverArtProvider.java
new file mode 100644
index 0000000..24f93f9
--- /dev/null
+++ b/src/com/android/bluetooth/avrcpcontroller/AvrcpCoverArtProvider.java
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2019 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.bluetooth.avrcpcontroller;
+
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothDevice;
+import android.content.ContentProvider;
+import android.content.ContentValues;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.ParcelFileDescriptor;
+import android.util.Log;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+
+/**
+ * A provider of downloaded cover art images.
+ *
+ * Cover art images are downloaded from remote devices and are promised to be "good" for the life of
+ * a connection.
+ *
+ * Android applications are provided a Uri with their MediaMetadata and MediaItem objects that
+ * points back to this provider. Uris are in the following format:
+ *
+ *   content://com.android.bluetooth.avrcpcontroller.AvrcpCoverArtProvider/<device>/<image-handle>
+ *
+ * It's expected by the Media framework that artwork at URIs will be available using the
+ * ContentResolver#openInputStream and BitmapFactory#decodeStream functions. Our provider must
+ * enable that usage pattern.
+ */
+public class AvrcpCoverArtProvider extends ContentProvider {
+    private static final String TAG = "AvrcpCoverArtProvider";
+    private static final boolean DBG = Log.isLoggable(TAG, Log.DEBUG);
+
+    private BluetoothAdapter mAdapter;
+    private AvrcpCoverArtStorage mStorage;
+
+    public AvrcpCoverArtProvider() {
+    }
+
+    static final String AUTHORITY = "com.android.bluetooth.avrcpcontroller.AvrcpCoverArtProvider";
+    static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY);
+
+    /**
+     * Get the Uri for a cover art image based on the device and image handle
+     *
+     * @param device The Bluetooth device from which an image originated
+     * @param imageHandle The provided handle of the cover artwork
+     * @return The Uri this provider will store the downloaded image at
+     */
+    public static Uri getImageUri(BluetoothDevice device, String imageHandle) {
+        if (device == null || imageHandle == null || "".equals(imageHandle)) return null;
+        Uri uri = CONTENT_URI.buildUpon().appendQueryParameter("device", device.getAddress())
+                .appendQueryParameter("handle", imageHandle)
+                .build();
+        debug("getImageUri -> " + uri.toString());
+        return uri;
+    }
+
+    private ParcelFileDescriptor getImageDescriptor(BluetoothDevice device, String imageHandle)
+            throws FileNotFoundException {
+        debug("getImageDescriptor(" + device + ", " + imageHandle + ")");
+        File file = mStorage.getImageFile(device, imageHandle);
+        if (file == null) throw new FileNotFoundException();
+        ParcelFileDescriptor pdf = ParcelFileDescriptor.open(file,
+                ParcelFileDescriptor.MODE_READ_ONLY);
+        return pdf;
+    }
+
+    @Override
+    public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {
+        debug("openFile(" + uri + ", '" + mode + "')");
+        String address = null;
+        String imageHandle = null;
+        BluetoothDevice device = null;
+        try {
+            address = uri.getQueryParameter("device");
+            imageHandle = uri.getQueryParameter("handle");
+        } catch (NullPointerException e) {
+            throw new FileNotFoundException();
+        }
+
+        try {
+            device = mAdapter.getRemoteDevice(address);
+        } catch (IllegalArgumentException e) {
+            throw new FileNotFoundException();
+        }
+
+        return getImageDescriptor(device, imageHandle);
+    }
+
+    @Override
+    public boolean onCreate() {
+        mAdapter = BluetoothAdapter.getDefaultAdapter();
+        mStorage = new AvrcpCoverArtStorage(getContext());
+        return true;
+    }
+
+    @Override
+    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
+            String sortOrder) {
+        return null;
+    }
+
+    @Override
+    public Uri insert(Uri uri, ContentValues values) {
+        return null;
+    }
+
+    @Override
+    public int delete(Uri uri, String selection, String[] selectionArgs) {
+        return 0;
+    }
+
+    @Override
+    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
+        return 0;
+    }
+
+    @Override
+    public String getType(Uri uri) {
+        return null;
+    }
+
+    private static void debug(String msg) {
+        if (DBG) {
+            Log.d(TAG, msg);
+        }
+    }
+}
diff --git a/src/com/android/bluetooth/avrcpcontroller/AvrcpCoverArtStorage.java b/src/com/android/bluetooth/avrcpcontroller/AvrcpCoverArtStorage.java
new file mode 100644
index 0000000..43ffdb4
--- /dev/null
+++ b/src/com/android/bluetooth/avrcpcontroller/AvrcpCoverArtStorage.java
@@ -0,0 +1,207 @@
+/*
+ * Copyright (C) 2019 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.bluetooth.avrcpcontroller;
+
+import android.bluetooth.BluetoothDevice;
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.net.Uri;
+import android.os.Environment;
+import android.util.Log;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+/**
+ * An abstraction of the file system storage of the downloaded cover art images.
+ */
+public class AvrcpCoverArtStorage {
+    private static final String TAG = "AvrcpCoverArtStorage";
+    private static final boolean DBG = Log.isLoggable(TAG, Log.DEBUG);
+
+    private final Context mContext;
+
+    /**
+     * Create and initialize this Cover Art storage interface
+     */
+    public AvrcpCoverArtStorage(Context context) {
+        mContext = context;
+    }
+
+    /**
+     * Determine if an image already exists in storage
+     *
+     * @param device - The device the images was downloaded from
+     * @param imageHandle - The handle that identifies the image
+     */
+    public boolean doesImageExist(BluetoothDevice device, String imageHandle) {
+        if (device == null || imageHandle == null || "".equals(imageHandle)) return false;
+        String path = getImagePath(device, imageHandle);
+        if (path == null) return false;
+        File file = new File(path);
+        return file.exists();
+    }
+
+    /**
+     * Retrieve an image file from storage
+     *
+     * @param device - The device the images was downloaded from
+     * @param imageHandle - The handle that identifies the image
+     * @return A file descriptor for the image
+     */
+    public File getImageFile(BluetoothDevice device, String imageHandle) {
+        if (device == null || imageHandle == null || "".equals(imageHandle)) return null;
+        String path = getImagePath(device, imageHandle);
+        if (path == null) return null;
+        File file = new File(path);
+        return file.exists() ? file : null;
+    }
+
+    /**
+     * Add an image to storage
+     *
+     * @param device - The device the images was downloaded from
+     * @param imageHandle - The handle that identifies the image
+     * @param image - The image
+     */
+    public Uri addImage(BluetoothDevice device, String imageHandle, Bitmap image) {
+        debug("Storing image '" + imageHandle + "' from device " + device);
+        if (device == null || imageHandle == null || "".equals(imageHandle) || image == null) {
+            debug("Cannot store image. Improper aruguments");
+            return null;
+        }
+
+        String path = getImagePath(device, imageHandle);
+        if (path == null) {
+            debug("Cannot store image. Cannot provide a valid path to storage");
+            return null;
+        }
+
+        try {
+            File deviceDirectory = new File(getDevicePath(device));
+            if (!deviceDirectory.exists()) {
+                deviceDirectory.mkdirs();
+            }
+
+            FileOutputStream outputStream = new FileOutputStream(path);
+            image.compress(Bitmap.CompressFormat.PNG, 100, outputStream);
+            outputStream.flush();
+            outputStream.close();
+        } catch (IOException e) {
+            error("Failed to store '" + imageHandle + "' to '" + path + "'");
+            return null;
+        }
+        Uri uri = AvrcpCoverArtProvider.getImageUri(device, imageHandle);
+        mContext.getContentResolver().notifyChange(uri, null);
+        debug("Image stored at '" + path + "'");
+        return uri;
+    }
+
+    /**
+     * Remove a specific image
+     *
+     * @param device The device you wish to have images removed for
+     * @param imageHandle The handle that identifies the image to delete
+     */
+    public void removeImage(BluetoothDevice device, String imageHandle) {
+        debug("Removing image '" + imageHandle + "' from device " + device);
+        if (device == null || imageHandle == null || "".equals(imageHandle)) return;
+        String path = getImagePath(device, imageHandle);
+        File file = new File(path);
+        if (!file.exists()) return;
+        file.delete();
+        debug("Image deleted at '" + path + "'");
+    }
+
+    /**
+     * Remove all stored images associated with a device
+     *
+     * @param device The device you wish to have images removed for
+     */
+    public void removeImagesForDevice(BluetoothDevice device) {
+        if (device == null) return;
+        debug("Remove cover art for device " + device.getAddress());
+        File deviceDirectory = new File(getDevicePath(device));
+        File[] files = deviceDirectory.listFiles();
+        if (files == null) {
+            debug("No cover art files to delete");
+            return;
+        }
+        for (int i = 0; i < files.length; i++) {
+            debug("Deleted " + files[i].getAbsolutePath());
+            files[i].delete();
+        }
+        deviceDirectory.delete();
+    }
+
+    private String getStorageDirectory() {
+        String dir = null;
+        if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
+            dir = mContext.getExternalFilesDir(null).getAbsolutePath() + "/coverart";
+        } else {
+            error("Cannot get storage directory, state=" + Environment.getExternalStorageState());
+        }
+        return dir;
+    }
+
+    private String getDevicePath(BluetoothDevice device) {
+        String storageDir = getStorageDirectory();
+        if (storageDir == null) return null;
+        return storageDir + "/" + device.getAddress().replace(":", "");
+    }
+
+    private String getImagePath(BluetoothDevice device, String imageHandle) {
+        String deviceDir = getDevicePath(device);
+        if (deviceDir == null) return null;
+        return deviceDir + "/" + imageHandle + ".png";
+    }
+
+    @Override
+    public String toString() {
+        String s = "CoverArtStorage:\n";
+        String storageDirectory = getStorageDirectory();
+        s += "    Storage Directory: " + storageDirectory + "\n";
+        if (storageDirectory == null) {
+            return s;
+        }
+
+        File storage = new File(storageDirectory);
+        File[] devices = storage.listFiles();
+        if (devices != null) {
+            for (File deviceDirectory : devices) {
+                s += "    " + deviceDirectory.getName() + ":\n";
+                File[] images = deviceDirectory.listFiles();
+                if (images == null) continue;
+                for (File image : images) {
+                    s += "      " + image.getName() + "\n";
+                }
+            }
+        }
+        return s;
+    }
+
+    private void debug(String msg) {
+        if (DBG) {
+            Log.d(TAG, msg);
+        }
+    }
+
+    private void error(String msg) {
+        Log.e(TAG, msg);
+    }
+}
diff --git a/src/com/android/bluetooth/avrcpcontroller/AvrcpItem.java b/src/com/android/bluetooth/avrcpcontroller/AvrcpItem.java
index 3864394..1ddcfda 100644
--- a/src/com/android/bluetooth/avrcpcontroller/AvrcpItem.java
+++ b/src/com/android/bluetooth/avrcpcontroller/AvrcpItem.java
@@ -39,7 +39,8 @@
     public static final int TYPE_FOLDER = 0x2;
     public static final int TYPE_MEDIA = 0x3;
 
-    // AVRCP Specification defined folder item sub types
+    // AVRCP Specification defined folder item sub types. These match with the Media Framework's
+    // definition of the constants as well.
     public static final int FOLDER_MIXED = 0x00;
     public static final int FOLDER_TITLES = 0x01;
     public static final int FOLDER_ALBUMS = 0x02;
@@ -59,6 +60,8 @@
     private int mItemType;
 
     // Sub type of item, dependant on whether it's a folder or media item
+    // Folder -> FOLDER_* constants
+    // Media -> MEDIA_* constants
     private int mType;
 
     // Bluetooth Device this piece of metadata came from
diff --git a/src/com/android/bluetooth/avrcpcontroller/AvrcpPlayer.java b/src/com/android/bluetooth/avrcpcontroller/AvrcpPlayer.java
index a693421..ba4beaa 100644
--- a/src/com/android/bluetooth/avrcpcontroller/AvrcpPlayer.java
+++ b/src/com/android/bluetooth/avrcpcontroller/AvrcpPlayer.java
@@ -17,6 +17,7 @@
 package com.android.bluetooth.avrcpcontroller;
 
 import android.bluetooth.BluetoothDevice;
+import android.net.Uri;
 import android.os.SystemClock;
 import android.support.v4.media.session.MediaSessionCompat;
 import android.support.v4.media.session.PlaybackStateCompat;
@@ -184,6 +185,15 @@
         mCurrentTrack = update;
     }
 
+    public synchronized boolean notifyImageDownload(String handle, Uri imageUri) {
+        if (DBG) Log.d(TAG, "Got an image download -- handle=" + handle + ", uri=" + imageUri);
+        if (mCurrentTrack != null && mCurrentTrack.getCoverArtHandle() == handle) {
+            mCurrentTrack.setCoverArtLocation(imageUri);
+            return true;
+        }
+        return false;
+    }
+
     public synchronized AvrcpItem getCurrentTrack() {
         return mCurrentTrack;
     }
diff --git a/src/com/android/bluetooth/avrcpcontroller/BrowseTree.java b/src/com/android/bluetooth/avrcpcontroller/BrowseTree.java
index 0af07d2..c9737e3 100644
--- a/src/com/android/bluetooth/avrcpcontroller/BrowseTree.java
+++ b/src/com/android/bluetooth/avrcpcontroller/BrowseTree.java
@@ -17,6 +17,7 @@
 package com.android.bluetooth.avrcpcontroller;
 
 import android.bluetooth.BluetoothDevice;
+import android.net.Uri;
 import android.support.v4.media.MediaBrowserCompat.MediaItem;
 import android.util.Log;
 
@@ -61,6 +62,10 @@
     final BrowseNode mNavigateUpNode;
     final BrowseNode mNowPlayingNode;
 
+    // In support of Cover Artwork, Cover Art URI <-> List of UUIDs using that artwork
+    private final HashMap<String, ArrayList<String>> mCoverArtMap =
+            new HashMap<String, ArrayList<String>>();
+
     BrowseTree(BluetoothDevice device) {
         if (device == null) {
             mRootNode = new BrowseNode(new AvrcpItem.Builder()
@@ -91,6 +96,7 @@
     public void clear() {
         // Clearing the map should garbage collect everything.
         mBrowseMap.clear();
+        mCoverArtMap.clear();
     }
 
     void onConnected(BluetoothDevice device) {
@@ -199,6 +205,7 @@
         synchronized void removeChild(BrowseNode node) {
             mChildren.remove(node);
             mBrowseMap.remove(node.getID());
+            indicateCoverArtUnused(node.getID(), node.getCoverArtHandle());
         }
 
         synchronized int getChildrenCount() {
@@ -224,6 +231,14 @@
             return mItem.getDevice();
         }
 
+        synchronized String getCoverArtHandle() {
+            return mItem.getCoverArtHandle();
+        }
+
+        synchronized void setCoverArtUri(Uri uri) {
+            mItem.setCoverArtLocation(uri);
+        }
+
         synchronized List<MediaItem> getContents() {
             if (mChildren.size() > 0 || mCached) {
                 List<MediaItem> contents = new ArrayList<MediaItem>(mChildren.size());
@@ -253,6 +268,7 @@
             if (!cached) {
                 for (BrowseNode child : mChildren) {
                     mBrowseMap.remove(child.getID());
+                    indicateCoverArtUnused(child.getID(), child.getCoverArtHandle());
                 }
                 mChildren.clear();
             }
@@ -396,11 +412,64 @@
         return mCurrentAddressedPlayer;
     }
 
+    /**
+     * Indicate that a node in the tree is using a specific piece of cover art, identified by the
+     * given image handle.
+     */
+    synchronized void indicateCoverArtUsed(String nodeId, String handle) {
+        mCoverArtMap.putIfAbsent(handle, new ArrayList<String>());
+        mCoverArtMap.get(handle).add(nodeId);
+    }
+
+    /**
+     * Indicate that a node in the tree no longer needs a specific piece of cover art.
+     */
+    synchronized void indicateCoverArtUnused(String nodeId, String handle) {
+        if (mCoverArtMap.containsKey(handle) && mCoverArtMap.get(handle).contains(nodeId)) {
+            mCoverArtMap.get(handle).remove(nodeId);
+            if (mCoverArtMap.get(handle).isEmpty()) {
+                mCoverArtMap.remove(handle);
+            }
+        }
+    }
+
+    /**
+     * Get a list of items using the piece of cover art identified by the given handle.
+     */
+    synchronized ArrayList<String> getNodesUsingCoverArt(String handle) {
+        if (!mCoverArtMap.containsKey(handle)) return new ArrayList<String>();
+        return (ArrayList<String>) mCoverArtMap.get(handle).clone();
+    }
+
+    /**
+     * Adds the Uri of a newly downloaded image to all tree nodes using that specific handle.
+     */
+    synchronized void notifyImageDownload(String handle, Uri uri) {
+        if (DBG) Log.d(TAG, "Received downloaded image handle to cascade to BrowseNodes using it");
+        ArrayList<String> nodes = getNodesUsingCoverArt(handle);
+        for (String nodeId : nodes) {
+            BrowseNode node = findBrowseNodeByID(nodeId);
+            if (node == null) {
+                Log.e(TAG, "Node was removed without clearing its cover art status");
+                indicateCoverArtUnused(nodeId, handle);
+                continue;
+            }
+            node.setCoverArtUri(uri);
+            indicateCoverArtUsed(nodeId, handle);
+            BluetoothMediaBrowserService.notifyChanged(node);
+        }
+    }
+
+
     @Override
     public String toString() {
         String serialized = "Size: " + mBrowseMap.size();
         if (VDBG) {
             serialized += mRootNode.toString();
+            serialized += "\n  Image handles in use (" + mCoverArtMap.size() + "):";
+            for (String handle : mCoverArtMap.keySet()) {
+                serialized += "    " + handle + "\n";
+            }
         }
         return serialized;
     }
diff --git a/src/com/android/bluetooth/avrcpcontroller/bip/BipAttachmentFormat.java b/src/com/android/bluetooth/avrcpcontroller/bip/BipAttachmentFormat.java
new file mode 100644
index 0000000..3760cb0
--- /dev/null
+++ b/src/com/android/bluetooth/avrcpcontroller/bip/BipAttachmentFormat.java
@@ -0,0 +1,172 @@
+/*
+ * Copyright (C) 2019 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.bluetooth.avrcpcontroller;
+
+import android.util.Log;
+
+import java.util.Date;
+import java.util.Objects;
+
+/**
+ * Represents BIP attachment metadata arriving from a GetImageProperties request.
+ *
+ * Content type is the only spec-required field.
+ *
+ * Examples:
+ *   <attachment content-type="text/plain" name="ABCD1234.txt" size="5120"/>
+ *   <attachment content-type="audio/basic" name="ABCD1234.wav" size="102400"/>
+ */
+public class BipAttachmentFormat {
+    private static final String TAG = "avrcpcontroller.BipAttachmentFormat";
+
+    /**
+     * MIME content type of the image attachment, i.e. "text/plain"
+     *
+     * This is required by the specification
+     */
+    private final String mContentType;
+
+    /**
+     * MIME character set of the image attachment, i.e. "ISO-8859-1"
+     */
+    private final String mCharset;
+
+    /**
+     * File name of the image attachment
+     *
+     * This is required by the specification
+     */
+    private final String mName;
+
+    /**
+     * Size of the image attachment in bytes
+     */
+    private final int mSize;
+
+    /**
+     * Date the image attachment was created
+     */
+    private final BipDateTime mCreated;
+
+    /**
+     * Date the image attachment was last modified
+     */
+    private final BipDateTime mModified;
+
+    public BipAttachmentFormat(String contentType, String charset, String name, String size,
+            String created, String modified) {
+        if (contentType == null) {
+            throw new ParseException("ContentType is required and must be valid");
+        }
+        if (name == null) {
+            throw new ParseException("Name is required and must be valid");
+        }
+
+        mContentType = contentType;
+        mName = name;
+        mCharset = charset;
+        mSize = parseInt(size);
+
+        BipDateTime bipCreated = null;
+        try {
+            bipCreated = new BipDateTime(created);
+        } catch (ParseException e) {
+            bipCreated = null;
+        }
+        mCreated = bipCreated;
+
+        BipDateTime bipModified = null;
+        try {
+            bipModified = new BipDateTime(modified);
+        } catch (ParseException e) {
+            bipModified = null;
+        }
+        mModified = bipModified;
+    }
+
+    public BipAttachmentFormat(String contentType, String charset, String name, int size,
+            Date created, Date modified) {
+        mContentType = Objects.requireNonNull(contentType, "Content-Type cannot be null");
+        mName = Objects.requireNonNull(name, "Name cannot be null");
+        mCharset = charset;
+        mSize = size;
+        mCreated = created != null ? new BipDateTime(created) : null;
+        mModified = modified != null ? new BipDateTime(modified) : null;
+    }
+
+    private static int parseInt(String s) {
+        if (s == null) return -1;
+        try {
+            return Integer.parseInt(s);
+        } catch (NumberFormatException e) {
+            Log.e(TAG, "Invalid number format for '" + s + "'");
+        }
+        return -1;
+    }
+
+    public String getContentType() {
+        return mContentType;
+    }
+
+    public String getName() {
+        return mName;
+    }
+
+    public String getCharset() {
+        return mCharset;
+    }
+
+    public int getSize() {
+        return mSize;
+    }
+
+    public BipDateTime getCreatedDate() {
+        return mCreated;
+    }
+
+    public BipDateTime getModifiedDate() {
+        return mModified;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (o == this) return true;
+        if (!(o instanceof BipAttachmentFormat)) return false;
+
+        BipAttachmentFormat a = (BipAttachmentFormat) o;
+        return a.getContentType() == getContentType()
+                && a.getName() == getName()
+                && a.getCharset() == getCharset()
+                && a.getSize() == getSize()
+                && a.getCreatedDate() == getCreatedDate()
+                && a.getModifiedDate() == getModifiedDate();
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        sb.append("<attachment");
+        sb.append(" content-type=\"" + mContentType + "\"");
+        if (mCharset != null) sb.append(" charset=\"" + mCharset + "\"");
+        sb.append(" name=\"" + mName + "\"");
+        if (mSize > -1) sb.append(" size=\"" + mSize + "\"");
+        if (mCreated != null) sb.append(" created=\"" + mCreated.toString() + "\"");
+        if (mModified != null) sb.append(" modified=\"" + mModified.toString() + "\"");
+        sb.append(" />");
+        return sb.toString();
+    }
+}
diff --git a/src/com/android/bluetooth/avrcpcontroller/bip/BipDateTime.java b/src/com/android/bluetooth/avrcpcontroller/bip/BipDateTime.java
new file mode 100644
index 0000000..bd648a4
--- /dev/null
+++ b/src/com/android/bluetooth/avrcpcontroller/bip/BipDateTime.java
@@ -0,0 +1,152 @@
+/*
+ * Copyright (C) 2019 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.bluetooth.avrcpcontroller;
+
+import java.util.Calendar;
+import java.util.Date;
+import java.util.Locale;
+import java.util.Objects;
+import java.util.TimeZone;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * An object representing a DateTime sent over the Basic Imaging Profile
+ *
+ * Date-time format is as follows:
+ *
+ *    YYYYMMDDTHHMMSSZ, where
+ *      Y/M/D/H/M/S - years, months, days, hours, minutes, seconds
+ *      T           - A delimiter
+ *      Z           - An optional, but recommended, character indicating the time is in UTC. If UTC
+ *                    is not used then we're to assume "local timezone" instead.
+ *
+ * Example date-time values:
+ *    20000101T000000Z
+ *    20000101T235959Z
+ *    20000101T000000
+ */
+public class BipDateTime {
+    private static final String TAG = "avrcpcontroller.BipDateTime";
+
+    private Date mDate = null;
+    private boolean mIsUtc = false;
+
+    public BipDateTime(String time) {
+        try {
+            /*
+            * Match groups for the timestamp are numbered as follows:
+            *
+            *     YYYY MM DD T HH MM SS Z
+            *     ^^^^ ^^ ^^   ^^ ^^ ^^ ^
+            *     1    2  3    4  5  6  7
+            */
+            Pattern p = Pattern.compile("(\\d{4})(\\d{2})(\\d{2})T(\\d{2})(\\d{2})(\\d{2})([Z])?");
+            Matcher m = p.matcher(time);
+
+            if (m.matches()) {
+                /* Default to system default and assume it knows best what our local timezone is */
+                Calendar.Builder builder = new Calendar.Builder();
+
+                /* Throw exceptions when given bad values */
+                builder.setLenient(false);
+
+                /* Note that Calendar months are zero-based in Java framework */
+                builder.setDate(Integer.parseInt(m.group(1)), /* year */
+                        Integer.parseInt(m.group(2)) - 1,     /* month */
+                        Integer.parseInt(m.group(3)));        /* day of month */
+
+                /* Note the timestamp doesn't have milliseconds and we're explicitly setting to 0 */
+                builder.setTimeOfDay(Integer.parseInt(m.group(4)), /* hours */
+                        Integer.parseInt(m.group(5)),              /* minutes */
+                        Integer.parseInt(m.group(6)),              /* seconds */
+                        0);                                        /* milliseconds */
+
+                /* If the 7th group is matched then we have UTC based timestamp */
+                if (m.group(7) != null) {
+                    TimeZone tz = TimeZone.getTimeZone("UTC");
+                    tz.setRawOffset(0);
+                    builder.setTimeZone(tz);
+                    mIsUtc = true;
+                } else {
+                    mIsUtc = false;
+                }
+
+                /* Note: Java dates are UTC and any date generated will be offset by the timezone */
+                mDate = builder.build().getTime();
+                return;
+            }
+        } catch (IllegalArgumentException e) {
+            // Let calendar bad values be caught and fall through
+        } catch (NullPointerException e) {
+            // Let null strings while matching fall through
+        }
+
+        // If we reach here then we've failed to parse the input string into a time
+        throw new ParseException("Failed to parse time '" + time + "'");
+    }
+
+    public BipDateTime(Date date) {
+        mDate = Objects.requireNonNull(date, "Date cannot be null");
+        mIsUtc = true; // All Java Date objects store timestamps as UTC
+    }
+
+    public boolean isUtc() {
+        return mIsUtc;
+    }
+
+    public Date getTime() {
+        return mDate;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (o == this) return true;
+        if (!(o instanceof BipDateTime)) return false;
+
+        BipDateTime d = (BipDateTime) o;
+        return d.isUtc() == isUtc() && d.getTime() == getTime();
+    }
+
+    @Override
+    public String toString() {
+        Date d = getTime();
+        if (d == null) {
+            return null;
+        }
+
+        Calendar cal = Calendar.getInstance();
+        cal.setTime(d);
+
+        /* Note that months are numbered stating from 0 */
+        if (isUtc()) {
+            TimeZone utc = TimeZone.getTimeZone("UTC");
+            utc.setRawOffset(0);
+            cal.setTimeZone(utc);
+            return String.format(Locale.US, "%04d%02d%02dT%02d%02d%02dZ", cal.get(Calendar.YEAR),
+                    cal.get(Calendar.MONTH) + 1, cal.get(Calendar.DATE),
+                    cal.get(Calendar.HOUR_OF_DAY), cal.get(Calendar.MINUTE),
+                    cal.get(Calendar.SECOND));
+        } else {
+            cal.setTimeZone(TimeZone.getDefault());
+            return String.format(Locale.US, "%04d%02d%02dT%02d%02d%02d", cal.get(Calendar.YEAR),
+                    cal.get(Calendar.MONTH) + 1, cal.get(Calendar.DATE),
+                    cal.get(Calendar.HOUR_OF_DAY), cal.get(Calendar.MINUTE),
+                    cal.get(Calendar.SECOND));
+        }
+    }
+}
diff --git a/src/com/android/bluetooth/avrcpcontroller/bip/BipEncoding.java b/src/com/android/bluetooth/avrcpcontroller/bip/BipEncoding.java
new file mode 100644
index 0000000..c4c401e
--- /dev/null
+++ b/src/com/android/bluetooth/avrcpcontroller/bip/BipEncoding.java
@@ -0,0 +1,194 @@
+/*
+ * Copyright (C) 2019 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.bluetooth.avrcpcontroller;
+
+import android.util.SparseArray;
+
+import java.util.HashMap;
+
+/**
+ * Represents an encoding method in which a BIP image is available.
+ *
+ * The encodings supported by this profile include:
+ *   - JPEG
+ *   - GIF
+ *   - WBMP
+ *   - PNG
+ *   - JPEG2000
+ *   - BMP
+ *   - USR-xxx
+ *
+ * The tag USR-xxx is used to represent proprietary encodings. The tag shall begin with the string
+ * “USR-” but the implementer assigns the characters of the second half of the string. This tag can
+ * be used by a manufacturer to enable its devices to exchange images under a proprietary encoding.
+ *
+ * Example proprietary encoding:
+ *
+ *   - USR-NOKIA-FORMAT1
+ */
+public class BipEncoding {
+    public static final int JPEG = 0;
+    public static final int PNG = 1;
+    public static final int BMP = 2;
+    public static final int GIF = 3;
+    public static final int JPEG2000 = 4;
+    public static final int WBMP = 5;
+    public static final int USR_XXX = 6;
+    public static final int UNKNOWN = 7; // i.e 'not assigned' or 'not assigned anything valid'
+
+    private static final HashMap sEncodingNamesToIds = new HashMap<String, Integer>();
+    static {
+        sEncodingNamesToIds.put("JPEG", JPEG);
+        sEncodingNamesToIds.put("GIF", GIF);
+        sEncodingNamesToIds.put("WBMP", WBMP);
+        sEncodingNamesToIds.put("PNG", PNG);
+        sEncodingNamesToIds.put("JPEG2000", JPEG2000);
+        sEncodingNamesToIds.put("BMP", BMP);
+    }
+
+    private static final SparseArray sIdsToEncodingNames = new SparseArray<String>();
+    static {
+        sIdsToEncodingNames.put(JPEG, "JPEG");
+        sIdsToEncodingNames.put(GIF, "GIF");
+        sIdsToEncodingNames.put(WBMP, "WBMP");
+        sIdsToEncodingNames.put(PNG, "PNG");
+        sIdsToEncodingNames.put(JPEG2000, "JPEG2000");
+        sIdsToEncodingNames.put(BMP, "BMP");
+        sIdsToEncodingNames.put(UNKNOWN, "UNKNOWN");
+    }
+
+    /**
+     * The integer ID of the type that this encoding is
+     */
+    private final int mType;
+
+    /**
+     * If an encoding is type USR_XXX then it has an extension that defines the encoding
+     */
+    private final String mProprietaryEncodingId;
+
+    /**
+     * Create an encoding object based on a AVRCP specification defined string of the encoding name
+     *
+     * @param encoding The encoding name
+     */
+    public BipEncoding(String encoding) {
+        if (encoding == null) {
+            throw new ParseException("Encoding input invalid");
+        }
+        encoding = encoding.trim();
+        mType = determineEncoding(encoding.toUpperCase());
+
+        String proprietaryEncodingId = null;
+        if (mType == USR_XXX) {
+            proprietaryEncodingId = encoding.substring(4).toUpperCase();
+        }
+        mProprietaryEncodingId = proprietaryEncodingId;
+
+        // If we don't have a type by now, we've failed to parse the encoding
+        if (mType == UNKNOWN) {
+            throw new ParseException("Failed to determine type of '" + encoding + "'");
+        }
+    }
+
+    /**
+     * Create an encoding object based on one of the constants for the available formats
+     *
+     * @param encoding A constant representing an available encoding
+     * @param proprietaryId A string representing the Id of a propreitary encoding. Only used if the
+     *                      encoding type is BipEncoding.USR_XXX
+     */
+    public BipEncoding(int encoding, String proprietaryId) {
+        if (encoding < 0 || encoding > USR_XXX) {
+            throw new IllegalArgumentException("Received invalid encoding type '" + encoding + "'");
+        }
+        mType = encoding;
+
+        String proprietaryEncodingId = null;
+        if (mType == USR_XXX) {
+            if (proprietaryId == null) {
+                throw new IllegalArgumentException("Received invalid user defined encoding id '"
+                        + proprietaryId + "'");
+            }
+            proprietaryEncodingId = proprietaryId.toUpperCase();
+        }
+        mProprietaryEncodingId = proprietaryEncodingId;
+    }
+
+    public BipEncoding(int encoding) {
+        this(encoding, null);
+    }
+
+    /**
+     * Returns the encoding type
+     *
+     * @return Integer type ID of the encoding
+     */
+    public int getType() {
+        return mType;
+    }
+
+    /**
+     * Returns the ID portion of an encoding if it's a proprietary encoding
+     *
+     * @return String ID of a proprietary encoding, or null if the encoding is not proprietary
+     */
+    public String getProprietaryEncodingId() {
+        return mProprietaryEncodingId;
+    }
+
+    /**
+     * Determines if an encoding is supported by Android's Graphics Framework
+     *
+     * Android's Bitmap/BitmapFactory can handle BMP, GIF, JPEG, PNG, WebP, and HEIF formats.
+     *
+     * @return True if the encoding is supported, False otherwise.
+     */
+    public boolean isAndroidSupported() {
+        return mType == BipEncoding.JPEG || mType == BipEncoding.PNG || mType == BipEncoding.BMP
+                || mType == BipEncoding.GIF;
+    }
+
+    /**
+     * Determine the encoding type based on an input string
+     */
+    private static int determineEncoding(String encoding) {
+        Integer type = (Integer) sEncodingNamesToIds.get(encoding);
+        if (type != null) return type.intValue();
+        if (encoding != null && encoding.length() >= 4 && encoding.substring(0, 4).equals("USR-")) {
+            return USR_XXX;
+        }
+        return UNKNOWN;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (o == this) return true;
+        if (!(o instanceof BipEncoding)) return false;
+
+        BipEncoding e = (BipEncoding) o;
+        return e.getType() == getType()
+                && e.getProprietaryEncodingId() == getProprietaryEncodingId();
+    }
+
+    @Override
+    public String toString() {
+        if (mType == USR_XXX) return "USR-" + mProprietaryEncodingId;
+        String encoding = (String) sIdsToEncodingNames.get(mType);
+        return encoding;
+    }
+}
diff --git a/src/com/android/bluetooth/avrcpcontroller/bip/BipImage.java b/src/com/android/bluetooth/avrcpcontroller/bip/BipImage.java
new file mode 100644
index 0000000..cb31f43
--- /dev/null
+++ b/src/com/android/bluetooth/avrcpcontroller/bip/BipImage.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2019 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.bluetooth.avrcpcontroller;
+
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+
+import java.io.InputStream;
+
+/**
+ * An image object sent over BIP.
+ *
+ * The image is sent as bytes in the payload of a GetImage request. The format of those bytes is
+ * determined by the BipImageDescriptor used when making the request.
+ */
+public class BipImage {
+    private final String mImageHandle;
+    private Bitmap mImage = null;
+
+    public BipImage(String imageHandle, InputStream inputStream) {
+        mImageHandle = imageHandle;
+        parse(inputStream);
+    }
+
+    public BipImage(String imageHandle, Bitmap image) {
+        mImageHandle = imageHandle;
+        mImage = image;
+    }
+
+    private void parse(InputStream inputStream) {
+        // BitmapFactory can handle BMP, GIF, JPEG, PNG, WebP, and HEIF formats. Returns null if
+        // the stream couldn't be parsed.
+        mImage = BitmapFactory.decodeStream(inputStream);
+    }
+
+    public String getImageHandle() {
+        return mImageHandle;
+    }
+
+    public Bitmap getImage() {
+        return mImage;
+    }
+}
diff --git a/src/com/android/bluetooth/avrcpcontroller/bip/BipImageDescriptor.java b/src/com/android/bluetooth/avrcpcontroller/bip/BipImageDescriptor.java
new file mode 100644
index 0000000..e6ba605
--- /dev/null
+++ b/src/com/android/bluetooth/avrcpcontroller/bip/BipImageDescriptor.java
@@ -0,0 +1,329 @@
+/*
+ * Copyright (C) 2019 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.bluetooth.avrcpcontroller;
+
+import android.util.Log;
+
+import com.android.internal.util.FastXmlSerializer;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlPullParserFactory;
+import org.xmlpull.v1.XmlSerializer;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.StringWriter;
+import java.io.UnsupportedEncodingException;
+
+/**
+ * Contains the metadata that describes either (1) the desired size of a image to be downloaded or
+ * (2) the extact size of an image to be uploaded.
+ *
+ * When using this to assert the size of an image to download/pull, it's best to derive this
+ * specific descriptor from any of the available BipImageFormat options returned from a
+ * RequestGetImageProperties. Note that if a BipImageFormat is not of a fixed size type then you
+ * must arrive on a desired fixed size for this descriptor.
+ *
+ * When using this to denote the size of an image when pushing an image for transfer this descriptor
+ * must match the metadata of the image being sent.
+ *
+ * Note, the encoding and pixel values are mandatory by specification. The version number is fixed.
+ * All other values are optional. The transformation field is to have *one* selected option in it.
+ *
+ * Example:
+ *   < image-descriptor version=“1.0” >
+ *   < image encoding=“JPEG” pixel=“1280*960” size=“500000”/>
+ *   < /image-descriptor >
+ */
+public class BipImageDescriptor {
+    private static final String TAG = "avrcpcontroller.BipImageDescriptor";
+    private static final String sVersion = "1.0";
+
+    /**
+     * A Builder for an ImageDescriptor object
+     */
+    public static class Builder {
+        private BipImageDescriptor mImageDescriptor = new BipImageDescriptor();
+        /**
+         * Set the encoding for the descriptor you're building using a BipEncoding object
+         *
+         * @param encoding The encoding you would like to set
+         * @return This object so you can continue building
+         */
+        public Builder setEncoding(BipEncoding encoding) {
+            mImageDescriptor.mEncoding = encoding;
+            return this;
+        }
+
+        /**
+         * Set the encoding for the descriptor you're building using a BipEncoding.* type value
+         *
+         * @param encoding The encoding you would like to set as a BipEncoding.* type value
+         * @return This object so you can continue building
+         */
+        public Builder setEncoding(int encoding) {
+            mImageDescriptor.mEncoding = new BipEncoding(encoding, null);
+            return this;
+        }
+
+        /**
+         * Set the encoding for the descriptor you're building using a BIP defined string name of
+         * the encoding you want
+         *
+         * @param encoding The encoding you would like to set as a BIP spec defined string
+         * @return This object so you can continue building
+         */
+        public Builder setPropietaryEncoding(String encoding) {
+            mImageDescriptor.mEncoding = new BipEncoding(BipEncoding.USR_XXX, encoding);
+            return this;
+        }
+
+        /**
+         * Set the fixed X by Y image dimensions for the descriptor you're building
+         *
+         * @param width The number of pixels in width of the image
+         * @param height The number of pixels in height of the image
+         * @return This object so you can continue building
+         */
+        public Builder setFixedDimensions(int width, int height) {
+            mImageDescriptor.mPixel = BipPixel.createFixed(width, height);
+            return this;
+        }
+
+        /**
+         * Set the transformation used for the descriptor you're building
+         *
+         * @param transformation The BipTransformation.* type value of the used transformation
+         * @return This object so you can continue building
+         */
+        public Builder setTransformation(int transformation) {
+            mImageDescriptor.mTransformation = new BipTransformation(transformation);
+            return this;
+        }
+
+        /**
+         * Set the image file size for the descriptor you're building
+         *
+         * @param size The image size in bytes
+         * @return This object so you can continue building
+         */
+        public Builder setFileSize(int size) {
+            mImageDescriptor.mSize = size;
+            return this;
+        }
+
+        /**
+         * Set the max file size of the image for the descriptor you're building
+         *
+         * @param size The maxe image size in bytes
+         * @return This object so you can continue building
+         */
+        public Builder setMaxFileSize(int size) {
+            mImageDescriptor.mMaxSize = size;
+            return this;
+        }
+
+        /**
+         * Build the object
+         *
+         * @return A BipImageDescriptor object
+         */
+        public BipImageDescriptor build() {
+            return mImageDescriptor;
+        }
+    }
+
+    /**
+     * The version of the image-descriptor XML string
+     */
+    private String mVersion = null;
+
+    /**
+     * The encoding of the image, required by the specification
+     */
+    private BipEncoding mEncoding = null;
+
+    /**
+     * The width and height of the image, required by the specification
+     */
+    private BipPixel mPixel = null;
+
+    /**
+     * The transformation to be applied to the image, *one* of BipTransformation.STRETCH,
+     * BipTransformation.CROP, or BipTransformation.FILL placed into a BipTransformation object
+     */
+    private BipTransformation mTransformation = null;
+
+    /**
+     * The size in bytes of the image
+     */
+    private int mSize = -1;
+
+    /**
+     * The max size in bytes of the image.
+     *
+     * Optional, used only when describing an image to pull
+     */
+    private int mMaxSize = -1;
+
+    private BipImageDescriptor() {
+        mVersion = sVersion;
+    }
+
+    public BipImageDescriptor(InputStream inputStream) {
+        parse(inputStream);
+    }
+
+    private void parse(InputStream inputStream) {
+        try {
+            XmlPullParser xpp = XmlPullParserFactory.newInstance().newPullParser();
+            xpp.setInput(inputStream, "utf-8");
+            int event = xpp.getEventType();
+            while (event != XmlPullParser.END_DOCUMENT) {
+                switch (event) {
+                    case XmlPullParser.START_TAG:
+                        String tag = xpp.getName();
+                        if (tag.equals("image-descriptor")) {
+                            mVersion = xpp.getAttributeValue(null, "version");
+                        } else if (tag.equals("image")) {
+                            mEncoding = new BipEncoding(xpp.getAttributeValue(null, "encoding"));
+                            mPixel = new BipPixel(xpp.getAttributeValue(null, "pixel"));
+                            mSize = parseInt(xpp.getAttributeValue(null, "size"));
+                            mMaxSize = parseInt(xpp.getAttributeValue(null, "maxsize"));
+                            mTransformation = new BipTransformation(
+                                        xpp.getAttributeValue(null, "transformation"));
+                        } else {
+                            Log.w(TAG, "Unrecognized tag in x-bt/img-Description object: " + tag);
+                        }
+                        break;
+                    case XmlPullParser.END_TAG:
+                        break;
+                }
+                event = xpp.next();
+            }
+            return;
+        } catch (XmlPullParserException e) {
+            Log.e(TAG, "XML parser error when parsing XML", e);
+        } catch (IOException e) {
+            Log.e(TAG, "I/O error when parsing XML", e);
+        }
+        throw new ParseException("Failed to parse image-descriptor from stream");
+    }
+
+    private static int parseInt(String s) {
+        if (s == null) return -1;
+        try {
+            return Integer.parseInt(s);
+        } catch (NumberFormatException e) {
+            error("Failed to parse '" + s + "'");
+        }
+        return -1;
+    }
+
+    public BipEncoding getEncoding() {
+        return mEncoding;
+    }
+
+    public BipPixel getPixel() {
+        return mPixel;
+    }
+
+    public BipTransformation getTransformation() {
+        return mTransformation;
+    }
+
+    public int getSize() {
+        return mSize;
+    }
+
+    public int getMaxSize() {
+        return mMaxSize;
+    }
+
+    /**
+     * Serialize this object into a byte array ready for transfer overOBEX
+     *
+     * @return A byte array containing this object's info, or null on error.
+     */
+    public byte[] serialize() {
+        String s = toString();
+        try {
+            return s != null ? s.getBytes("UTF-8") : null;
+        } catch (UnsupportedEncodingException e) {
+            return null;
+        }
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (o == this) return true;
+        if (!(o instanceof BipImageDescriptor)) return false;
+
+        BipImageDescriptor d = (BipImageDescriptor) o;
+        return d.getEncoding() == getEncoding()
+                && d.getPixel() == getPixel()
+                && d.getTransformation() == getTransformation()
+                && d.getSize() == getSize()
+                && d.getMaxSize() == getMaxSize();
+    }
+
+    @Override
+    public String toString() {
+        if (mEncoding == null || mPixel == null) {
+            error("Missing required fields [ " + (mEncoding == null ? "encoding " : "")
+                    + (mPixel == null ? "pixel " : ""));
+            return null;
+        }
+        StringWriter writer = new StringWriter();
+        XmlSerializer xmlMsgElement = new FastXmlSerializer();
+        try {
+            xmlMsgElement.setOutput(writer);
+            xmlMsgElement.startDocument("UTF-8", true);
+            xmlMsgElement.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
+            xmlMsgElement.startTag(null, "image-descriptor");
+            xmlMsgElement.attribute(null, "version", sVersion);
+            xmlMsgElement.startTag(null, "image");
+            xmlMsgElement.attribute(null, "encoding", mEncoding.toString());
+            xmlMsgElement.attribute(null, "pixel", mPixel.toString());
+            if (mSize != -1) {
+                xmlMsgElement.attribute(null, "size", Integer.toString(mSize));
+            }
+            if (mMaxSize != -1) {
+                xmlMsgElement.attribute(null, "maxsize", Integer.toString(mMaxSize));
+            }
+            if (mTransformation != null && mTransformation.supportsAny()) {
+                xmlMsgElement.attribute(null, "transformation", mTransformation.toString());
+            }
+            xmlMsgElement.endTag(null, "image");
+            xmlMsgElement.endTag(null, "image-descriptor");
+            xmlMsgElement.endDocument();
+            return writer.toString();
+        } catch (IllegalArgumentException e) {
+            error(e.toString());
+        } catch (IllegalStateException e) {
+            error(e.toString());
+        } catch (IOException e) {
+            error(e.toString());
+        }
+        return null;
+    }
+
+    private static void error(String msg) {
+        Log.e(TAG, msg);
+    }
+}
diff --git a/src/com/android/bluetooth/avrcpcontroller/bip/BipImageFormat.java b/src/com/android/bluetooth/avrcpcontroller/bip/BipImageFormat.java
new file mode 100644
index 0000000..43cbef9
--- /dev/null
+++ b/src/com/android/bluetooth/avrcpcontroller/bip/BipImageFormat.java
@@ -0,0 +1,228 @@
+/*
+ * Copyright (C) 2019 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.bluetooth.avrcpcontroller;
+
+import android.util.Log;
+
+import java.util.Objects;
+
+/**
+ * Describes a single native or variant format available for an image, coming from a
+ * BipImageProperties object.
+ *
+ * This is not an object by specification, per say. It abstracts all the various native and variant
+ * formats available in a given set of image properties.
+ *
+ * This BipImageFormat can be used to choose a specific BipImageDescriptor when downloading an image
+ *
+ * Examples:
+ *   <native encoding="JPEG" pixel="1280*1024” size="1048576"/>
+ *   <variant encoding="JPEG" pixel="640*480"/>
+ *   <variant encoding="JPEG" pixel="160*120"/>
+ *   <variant encoding="GIF" pixel="80*60-640*480"/>
+ */
+public class BipImageFormat {
+    private static final String TAG = "avrcpcontroller.BipImageFormat";
+
+    public static final int FORMAT_NATIVE = 0;
+    public static final int FORMAT_VARIANT = 1;
+
+    /**
+     * Create a native BipImageFormat from the given string fields
+     */
+    public static BipImageFormat parseNative(String encoding, String pixel, String size) {
+        return new BipImageFormat(BipImageFormat.FORMAT_NATIVE, encoding, pixel, size, null, null);
+    }
+
+    /**
+     * Create a variant BipImageFormat from the given string fields
+     */
+    public static BipImageFormat parseVariant(String encoding, String pixel, String maxSize,
+            String transformation) {
+        return new BipImageFormat(BipImageFormat.FORMAT_VARIANT, encoding, pixel, null, maxSize,
+                transformation);
+    }
+
+    /**
+     * Create a native BipImageFormat from the given parameters
+     */
+    public static BipImageFormat createNative(BipEncoding encoding, BipPixel pixel, int size) {
+        return new BipImageFormat(BipImageFormat.FORMAT_NATIVE, encoding, pixel, size, -1, null);
+    }
+
+    /**
+     * Create a variant BipImageFormat from the given parameters
+     */
+    public static BipImageFormat createVariant(BipEncoding encoding, BipPixel pixel, int maxSize,
+            BipTransformation transformation) {
+        return new BipImageFormat(BipImageFormat.FORMAT_VARIANT, encoding, pixel, -1, maxSize,
+                transformation);
+    }
+
+    /**
+     * The 'flavor' of this image format, from the format constants above.
+     */
+    private final int mFormatType;
+
+    /**
+     * The encoding method in which this image is available, required by the specification
+     */
+    private final BipEncoding mEncoding;
+
+    /**
+     * The pixel size or range of pixel sizes in which the image is available, required by the
+     * specification
+     */
+    private final BipPixel mPixel;
+
+    /**
+     * The list of supported image transformation methods, any of:
+     *   - 'stretch' : Image server is capable of stretching the image to fit a space
+     *   - 'fill' : Image server is capable of filling the image padding data to fit a space
+     *   - 'crop' : Image server is capable of cropping the image down to fit a space
+     *
+     * Used by the variant type only
+     */
+    private final BipTransformation mTransformation;
+
+    /**
+     * Size in bytes of the image.
+     *
+     * Used by the native type only
+     */
+    private final int mSize;
+
+    /**
+     * The estimated maximum size of an image after a transformation is performed.
+     *
+     * Used by the variant type only
+     */
+    private final int mMaxSize;
+
+    private BipImageFormat(int type, BipEncoding encoding, BipPixel pixel, int size, int maxSize,
+            BipTransformation transformation) {
+        mFormatType = type;
+        mEncoding = Objects.requireNonNull(encoding, "Encoding cannot be null");
+        mPixel = Objects.requireNonNull(pixel, "Pixel cannot be null");
+        mTransformation = transformation;
+        mSize = size;
+        mMaxSize = maxSize;
+    }
+
+    private BipImageFormat(int type, String encoding, String pixel, String size, String maxSize,
+            String transformation) {
+        mFormatType = type;
+        mEncoding = new BipEncoding(encoding);
+        mPixel = new BipPixel(pixel);
+        mTransformation = new BipTransformation(transformation);
+        mSize = parseInt(size);
+        mMaxSize = parseInt(maxSize);
+    }
+
+    private static int parseInt(String s) {
+        if (s == null) return -1;
+        try {
+            return Integer.parseInt(s);
+        } catch (NumberFormatException e) {
+            error("Failed to parse '" + s + "'");
+        }
+        return -1;
+    }
+
+    public int getType() {
+        return mFormatType;
+    }
+
+    public BipEncoding getEncoding() {
+        return mEncoding;
+    }
+
+    public BipPixel getPixel() {
+        return mPixel;
+    }
+
+    public BipTransformation getTransformation() {
+        return mTransformation;
+    }
+
+    public int getSize() {
+        return mSize;
+    }
+
+    public int getMaxSize() {
+        return mMaxSize;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (o == this) return true;
+        if (!(o instanceof BipImageFormat)) return false;
+
+        BipImageFormat f = (BipImageFormat) o;
+        return f.getType() == getType()
+                && f.getEncoding() == getEncoding()
+                && f.getPixel() == getPixel()
+                && f.getTransformation() == getTransformation()
+                && f.getSize() == getSize()
+                && f.getMaxSize() == getMaxSize();
+    }
+
+    @Override
+    public String toString() {
+        if (mEncoding == null || mEncoding.getType() == BipEncoding.UNKNOWN || mPixel == null
+                || mPixel.getType() == BipPixel.TYPE_UNKNOWN) {
+            error("Missing required fields [ " + (mEncoding == null ? "encoding " : "")
+                    + (mPixel == null ? "pixel " : ""));
+            return null;
+        }
+
+        StringBuilder sb = new StringBuilder();
+        switch (mFormatType) {
+            case FORMAT_NATIVE:
+                sb.append("<native");
+                sb.append(" encoding=\"" + mEncoding.toString() + "\"");
+                sb.append(" pixel=\"" + mPixel.toString() + "\"");
+                if (mSize > -1) {
+                    sb.append(" size=\"" + mSize + "\"");
+                }
+                sb.append(" />");
+                return sb.toString();
+            case FORMAT_VARIANT:
+                sb.append("<variant");
+                sb.append(" encoding=\"" + mEncoding.toString() + "\"");
+                sb.append(" pixel=\"" + mPixel.toString() + "\"");
+                if (mTransformation != null && mTransformation.supportsAny()) {
+                    sb.append(" transformation=\"" + mTransformation.toString() + "\"");
+                }
+                if (mSize > -1) {
+                    sb.append(" size=\"" + mSize + "\"");
+                }
+                if (mMaxSize > -1) {
+                    sb.append(" maxsize=\"" + mMaxSize + "\"");
+                }
+                sb.append(" />");
+                return sb.toString();
+            default:
+                error("Unsupported format type '" + mFormatType + "'");
+        }
+        return null;
+    }
+
+    private static void error(String msg) {
+        Log.e(TAG, msg);
+    }
+}
diff --git a/src/com/android/bluetooth/avrcpcontroller/bip/BipImageProperties.java b/src/com/android/bluetooth/avrcpcontroller/bip/BipImageProperties.java
new file mode 100644
index 0000000..70d935a
--- /dev/null
+++ b/src/com/android/bluetooth/avrcpcontroller/bip/BipImageProperties.java
@@ -0,0 +1,379 @@
+/*
+ * Copyright (C) 2019 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.bluetooth.avrcpcontroller;
+
+import android.util.Log;
+
+import com.android.internal.util.FastXmlSerializer;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlPullParserFactory;
+import org.xmlpull.v1.XmlSerializer;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.StringWriter;
+import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
+import java.util.Objects;
+
+/**
+ * Represents the return value of a BIP GetImageProperties request, giving a detailed description of
+ * an image and its available descriptors before download.
+ *
+ * Format is as described by version 1.2.1 of the Basic Image Profile Specification. The
+ * specification describes three types of metadata that can arrive with an image -- native, variant
+ * and attachment. Native describes which native formats a particular image is available in.
+ * Variant describes which other types of encodings/sizes can be created from the native image using
+ * various transformations. Attachments describes other items that can be downloaded that are
+ * associated with the image (text, sounds, etc.)
+ *
+ * Example:
+ *     <image-properties version="1.0" handle="123456789">
+ *     <native encoding="JPEG" pixel="1280*1024" size="1048576"/>
+ *     <variant encoding="JPEG" pixel="640*480" />
+ *     <variant encoding="JPEG" pixel="160*120" />
+ *     <variant encoding="GIF" pixel="80*60-640*480" transformation="stretch fill crop"/>
+ *     <attachment content-type="text/plain" name="ABCD1234.txt" size="5120"/>
+ *     <attachment content-type="audio/basic" name="ABCD1234.wav" size="102400"/>
+ *     </image-properties>
+ */
+public class BipImageProperties {
+    private static final String TAG = "avrcpcontroller.BipImageProperties";
+    private static final String sVersion = "1.0";
+
+    /**
+     * A Builder for a BipImageProperties object
+     */
+    public static class Builder {
+        private BipImageProperties mProperties = new BipImageProperties();
+        /**
+         * Set the image handle field for the object you're building
+         *
+         * @param handle The image handle you want to add to the object
+         * @return The builder object to keep building on top of
+         */
+        public Builder setImageHandle(String handle) {
+            mProperties.mImageHandle = handle;
+            return this;
+        }
+
+        /**
+         * Set the FriendlyName field for the object you're building
+         *
+         * @param friendlyName The friendly name you want to add to the object
+         * @return The builder object to keep building on top of
+         */
+        public Builder setFriendlyName(String friendlyName) {
+            mProperties.mFriendlyName = friendlyName;
+            return this;
+        }
+
+        /**
+         * Add a native format for the object you're building
+         *
+         * @param format The format you want to add to the object
+         * @return The builder object to keep building on top of
+         */
+        public Builder addNativeFormat(BipImageFormat format) {
+            mProperties.addNativeFormat(format);
+            return this;
+        }
+
+        /**
+         * Add a variant format for the object you're building
+         *
+         * @param format The format you want to add to the object
+         * @return The builder object to keep building on top of
+         */
+        public Builder addVariantFormat(BipImageFormat format) {
+            mProperties.addVariantFormat(format);
+            return this;
+        }
+
+        /**
+         * Add an attachment entry for the object you're building
+         *
+         * @param format The format you want to add to the object
+         * @return The builder object to keep building on top of
+         */
+        public Builder addAttachment(BipAttachmentFormat format) {
+            mProperties.addAttachment(format);
+            return this;
+        }
+
+        /**
+         * Build the object
+         *
+         * @return A BipImageProperties object
+         */
+        public BipImageProperties build() {
+            return mProperties;
+        }
+    }
+
+    /**
+     * The image handle associated with this set of properties.
+     */
+    private String mImageHandle = null;
+
+    /**
+     * The version of the properties object, used to encode and decode.
+     */
+    private String mVersion = null;
+
+    /**
+     * An optional friendly name for the associated image. The specification suggests the file name.
+     */
+    private String mFriendlyName = null;
+
+    /**
+     * The various sets of available formats.
+     */
+    private ArrayList<BipImageFormat> mNativeFormats;
+    private ArrayList<BipImageFormat> mVariantFormats;
+    private ArrayList<BipAttachmentFormat> mAttachments;
+
+    private BipImageProperties() {
+        mVersion = sVersion;
+        mNativeFormats = new ArrayList<BipImageFormat>();
+        mVariantFormats = new ArrayList<BipImageFormat>();
+        mAttachments = new ArrayList<BipAttachmentFormat>();
+    }
+
+    public BipImageProperties(InputStream inputStream) {
+        mNativeFormats = new ArrayList<BipImageFormat>();
+        mVariantFormats = new ArrayList<BipImageFormat>();
+        mAttachments = new ArrayList<BipAttachmentFormat>();
+        parse(inputStream);
+    }
+
+    private void parse(InputStream inputStream) {
+        try {
+            XmlPullParser xpp = XmlPullParserFactory.newInstance().newPullParser();
+            xpp.setInput(inputStream, "utf-8");
+            int event = xpp.getEventType();
+            while (event != XmlPullParser.END_DOCUMENT) {
+                switch (event) {
+                    case XmlPullParser.START_TAG:
+                        String tag = xpp.getName();
+                        if (tag.equals("image-properties")) {
+                            mVersion = xpp.getAttributeValue(null, "version");
+                            mImageHandle = xpp.getAttributeValue(null, "handle");
+                            mFriendlyName = xpp.getAttributeValue(null, "friendly-name");
+                        } else if (tag.equals("native")) {
+                            String encoding = xpp.getAttributeValue(null, "encoding");
+                            String pixel = xpp.getAttributeValue(null, "pixel");
+                            String size = xpp.getAttributeValue(null, "size");
+                            addNativeFormat(BipImageFormat.parseNative(encoding, pixel, size));
+                        } else if (tag.equals("variant")) {
+                            String encoding = xpp.getAttributeValue(null, "encoding");
+                            String pixel = xpp.getAttributeValue(null, "pixel");
+                            String maxSize = xpp.getAttributeValue(null, "maxsize");
+                            String trans = xpp.getAttributeValue(null, "transformation");
+                            addVariantFormat(
+                                    BipImageFormat.parseVariant(encoding, pixel, maxSize, trans));
+                        } else if (tag.equals("attachment")) {
+                            String contentType = xpp.getAttributeValue(null, "content-type");
+                            String name = xpp.getAttributeValue(null, "name");
+                            String charset = xpp.getAttributeValue(null, "charset");
+                            String size = xpp.getAttributeValue(null, "size");
+                            String created = xpp.getAttributeValue(null, "created");
+                            String modified = xpp.getAttributeValue(null, "modified");
+                            addAttachment(
+                                    new BipAttachmentFormat(contentType, charset, name, size,
+                                            created, modified));
+                        } else {
+                            warn("Unrecognized tag in x-bt/img-properties object: " + tag);
+                        }
+                        break;
+                    case XmlPullParser.END_TAG:
+                        break;
+                }
+                event = xpp.next();
+            }
+            return;
+        } catch (XmlPullParserException e) {
+            error("XML parser error when parsing XML", e);
+        } catch (IOException e) {
+            error("I/O error when parsing XML", e);
+        }
+        throw new ParseException("Failed to parse image-properties from stream");
+    }
+
+    public String getImageHandle() {
+        return mImageHandle;
+    }
+
+    public String getFriendlyName() {
+        return mFriendlyName;
+    }
+
+    public ArrayList<BipImageFormat> getNativeFormats() {
+        return mNativeFormats;
+    }
+
+    public ArrayList<BipImageFormat> getVariantFormats() {
+        return mVariantFormats;
+    }
+
+    public ArrayList<BipAttachmentFormat> getAttachments() {
+        return mAttachments;
+    }
+
+    private void addNativeFormat(BipImageFormat format) {
+        Objects.requireNonNull(format);
+        if (format.getType() != BipImageFormat.FORMAT_NATIVE) {
+            throw new IllegalArgumentException("Format type '" + format.getType()
+                    + "' but expected '" + BipImageFormat.FORMAT_NATIVE + "'");
+        }
+        mNativeFormats.add(format);
+    }
+
+    private void addVariantFormat(BipImageFormat format) {
+        Objects.requireNonNull(format);
+        if (format.getType() != BipImageFormat.FORMAT_VARIANT) {
+            throw new IllegalArgumentException("Format type '" + format.getType()
+                    + "' but expected '" + BipImageFormat.FORMAT_VARIANT + "'");
+        }
+        mVariantFormats.add(format);
+    }
+
+    private void addAttachment(BipAttachmentFormat format) {
+        Objects.requireNonNull(format);
+        mAttachments.add(format);
+    }
+
+    @Override
+    public String toString() {
+        StringWriter writer = new StringWriter();
+        XmlSerializer xmlMsgElement = new FastXmlSerializer();
+        try {
+            xmlMsgElement.setOutput(writer);
+            xmlMsgElement.startDocument("UTF-8", true);
+            xmlMsgElement.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
+            xmlMsgElement.startTag(null, "image-properties");
+            xmlMsgElement.attribute(null, "version", mVersion);
+            xmlMsgElement.attribute(null, "handle", mImageHandle);
+
+            for (BipImageFormat format : mNativeFormats) {
+                BipEncoding encoding = format.getEncoding();
+                BipPixel pixel = format.getPixel();
+                int size = format.getSize();
+                if (encoding == null || pixel == null) {
+                    error("Native format " + format.toString() + " is invalid.");
+                    continue;
+                }
+                xmlMsgElement.startTag(null, "native");
+                xmlMsgElement.attribute(null, "encoding", encoding.toString());
+                xmlMsgElement.attribute(null, "pixel", pixel.toString());
+                if (size >= 0) {
+                    xmlMsgElement.attribute(null, "size", Integer.toString(size));
+                }
+                xmlMsgElement.endTag(null, "native");
+            }
+
+            for (BipImageFormat format : mVariantFormats) {
+                BipEncoding encoding = format.getEncoding();
+                BipPixel pixel = format.getPixel();
+                int maxSize = format.getMaxSize();
+                BipTransformation trans = format.getTransformation();
+                if (encoding == null || pixel == null) {
+                    error("Variant format " + format.toString() + " is invalid.");
+                    continue;
+                }
+                xmlMsgElement.startTag(null, "variant");
+                xmlMsgElement.attribute(null, "encoding", encoding.toString());
+                xmlMsgElement.attribute(null, "pixel", pixel.toString());
+                if (maxSize >= 0) {
+                    xmlMsgElement.attribute(null, "maxsize", Integer.toString(maxSize));
+                }
+                if (trans != null && trans.supportsAny()) {
+                    xmlMsgElement.attribute(null, "transformation", trans.toString());
+                }
+                xmlMsgElement.endTag(null, "variant");
+            }
+
+            for (BipAttachmentFormat format : mAttachments) {
+                String contentType = format.getContentType();
+                String charset = format.getCharset();
+                String name = format.getName();
+                int size = format.getSize();
+                BipDateTime created = format.getCreatedDate();
+                BipDateTime modified = format.getModifiedDate();
+                if (contentType == null || name == null) {
+                    error("Attachment format " + format.toString() + " is invalid.");
+                    continue;
+                }
+                xmlMsgElement.startTag(null, "attachment");
+                xmlMsgElement.attribute(null, "content-type", contentType.toString());
+                if (charset != null) {
+                    xmlMsgElement.attribute(null, "charset", charset.toString());
+                }
+                xmlMsgElement.attribute(null, "name", name.toString());
+                if (size >= 0) {
+                    xmlMsgElement.attribute(null, "size", Integer.toString(size));
+                }
+                if (created != null) {
+                    xmlMsgElement.attribute(null, "created", created.toString());
+                }
+                if (modified != null) {
+                    xmlMsgElement.attribute(null, "modified", modified.toString());
+                }
+                xmlMsgElement.endTag(null, "attachment");
+            }
+
+            xmlMsgElement.endTag(null, "image-properties");
+            xmlMsgElement.endDocument();
+            return writer.toString();
+        } catch (IllegalArgumentException e) {
+            error("Falied to serialize ImageProperties", e);
+        } catch (IllegalStateException e) {
+            error("Falied to serialize ImageProperties", e);
+        } catch (IOException e) {
+            error("Falied to serialize ImageProperties", e);
+        }
+        return null;
+    }
+
+    /**
+     * Serialize this object into a byte array
+     *
+     * @return Byte array representing this object, ready to send over OBEX, or null on error.
+     */
+    public byte[] serialize() {
+        String s = toString();
+        try {
+            return s != null ? s.getBytes("UTF-8") : null;
+        } catch (UnsupportedEncodingException e) {
+            return null;
+        }
+    }
+
+    private static void warn(String msg) {
+        Log.w(TAG, msg);
+    }
+
+    private static void error(String msg) {
+        Log.e(TAG, msg);
+    }
+
+    private static void error(String msg, Throwable e) {
+        Log.e(TAG, msg, e);
+    }
+}
diff --git a/src/com/android/bluetooth/avrcpcontroller/bip/BipPixel.java b/src/com/android/bluetooth/avrcpcontroller/bip/BipPixel.java
new file mode 100644
index 0000000..bba0cef
--- /dev/null
+++ b/src/com/android/bluetooth/avrcpcontroller/bip/BipPixel.java
@@ -0,0 +1,243 @@
+/*
+ * Copyright (C) 2019 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.bluetooth.avrcpcontroller;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * The pixel size or range of pixel sizes in which the image is available
+ *
+ * A FIXED size is represented as the following, where W is width and H is height. The domain
+ * of values is [0, 65535]
+ *
+ *   W*H
+ *
+ * A RESIZABLE size that allows a modified aspect ratio is represented as the following, where
+ * W_1*H_1 is the minimum width and height pair and W2*H2 is the maximum width and height pair.
+ * The domain of values is [0, 65535]
+ *
+ *   W_1*H_1-W2*H2
+ *
+ * A RESIZABLE size that allows a fixed aspect ratio is represented as the following, where
+ * W_1 is the minimum width and W2*H2 is the maximum width and height pair.
+ * The domain of values is [0, 65535]
+ *
+ *   W_1**-W2*H2
+ *
+ * For each possible intermediate width value, the corresponding height is calculated using the
+ * formula
+ *
+ *   H=(W*H2)/W2
+ */
+public class BipPixel {
+    private static final String TAG = "avrcpcontroller.BipPixel";
+
+    // The BIP specification declares this as the max size to be transferred. You can optionally
+    // use this value to indicate there is no upper bound on pixel size.
+    public static final int PIXEL_MAX = 65535;
+
+    // Note that the integer values also map to the number of '*' delimiters that exist in each
+    // formatted string
+    public static final int TYPE_UNKNOWN = 0;
+    public static final int TYPE_FIXED = 1;
+    public static final int TYPE_RESIZE_MODIFIED_ASPECT_RATIO = 2;
+    public static final int TYPE_RESIZE_FIXED_ASPECT_RATIO = 3;
+
+    private final int mType;
+    private final int mMinWidth;
+    private final int mMinHeight;
+    private final int mMaxWidth;
+    private final int mMaxHeight;
+
+    /**
+     * Create a fixed size BipPixel object
+     */
+    public static BipPixel createFixed(int width, int height) {
+        return new BipPixel(TYPE_FIXED, width, height, width, height);
+    }
+
+    /**
+     * Create a resizable modifiable aspect ratio BipPixel object
+     */
+    public static BipPixel createResizableModified(int minWidth, int minHeight, int maxWidth,
+            int maxHeight) {
+        return new BipPixel(TYPE_RESIZE_MODIFIED_ASPECT_RATIO, minWidth, minHeight, maxWidth,
+                maxHeight);
+    }
+
+    /**
+     * Create a resizable fixed aspect ratio BipPixel object
+     */
+    public static BipPixel createResizableFixed(int minWidth, int maxWidth, int maxHeight) {
+        int minHeight = (minWidth * maxHeight) / maxWidth;
+        return new BipPixel(TYPE_RESIZE_FIXED_ASPECT_RATIO, minWidth, minHeight,
+                maxWidth, maxHeight);
+    }
+
+    /**
+     * Directly create a BipPixel object knowing your exact type and dimensions. Internal use only
+     */
+    private BipPixel(int type, int minWidth, int minHeight, int maxWidth, int maxHeight) {
+        if (isDimensionInvalid(minWidth) || isDimensionInvalid(maxWidth)
+                || isDimensionInvalid(minHeight) || isDimensionInvalid(maxHeight)) {
+            throw new IllegalArgumentException("Dimension's must be in [0, " + PIXEL_MAX + "]");
+        }
+
+        mType = type;
+        mMinWidth = minWidth;
+        mMinHeight = minHeight;
+        mMaxWidth = maxWidth;
+        mMaxHeight = maxHeight;
+    }
+
+    /**
+    * Create a BipPixel object from an Image Format pixel attribute string
+     */
+    public BipPixel(String pixel) {
+        int type = TYPE_UNKNOWN;
+        int minWidth = -1;
+        int minHeight = -1;
+        int maxWidth = -1;
+        int maxHeight = -1;
+
+        int typeHint = determinePixelType(pixel);
+        switch (typeHint) {
+            case TYPE_FIXED:
+                Pattern fixed = Pattern.compile("^(\\d{1,5})\\*(\\d{1,5})$");
+                Matcher m1 = fixed.matcher(pixel);
+                if (m1.matches()) {
+                    type = TYPE_FIXED;
+                    minWidth = Integer.parseInt(m1.group(1));
+                    maxWidth = Integer.parseInt(m1.group(1));
+                    minHeight = Integer.parseInt(m1.group(2));
+                    maxHeight = Integer.parseInt(m1.group(2));
+                }
+                break;
+            case TYPE_RESIZE_MODIFIED_ASPECT_RATIO:
+                Pattern modifiedRatio = Pattern.compile(
+                        "^(\\d{1,5})\\*(\\d{1,5})-(\\d{1,5})\\*(\\d{1,5})$");
+                Matcher m2 = modifiedRatio.matcher(pixel);
+                if (m2.matches()) {
+                    type = TYPE_RESIZE_MODIFIED_ASPECT_RATIO;
+                    minWidth = Integer.parseInt(m2.group(1));
+                    minHeight = Integer.parseInt(m2.group(2));
+                    maxWidth = Integer.parseInt(m2.group(3));
+                    maxHeight = Integer.parseInt(m2.group(4));
+                }
+                break;
+            case TYPE_RESIZE_FIXED_ASPECT_RATIO:
+                Pattern fixedRatio = Pattern.compile("^(\\d{1,5})\\*\\*-(\\d{1,5})\\*(\\d{1,5})$");
+                Matcher m3 = fixedRatio.matcher(pixel);
+                if (m3.matches()) {
+                    type = TYPE_RESIZE_FIXED_ASPECT_RATIO;
+                    minWidth = Integer.parseInt(m3.group(1));
+                    maxWidth = Integer.parseInt(m3.group(2));
+                    maxHeight = Integer.parseInt(m3.group(3));
+                    minHeight = (minWidth * maxHeight) / maxWidth;
+                }
+                break;
+            default:
+                break;
+        }
+        if (type == TYPE_UNKNOWN) {
+            throw new ParseException("Failed to determine type of '" + pixel + "'");
+        }
+        if (isDimensionInvalid(minWidth) || isDimensionInvalid(maxWidth)
+                || isDimensionInvalid(minHeight) || isDimensionInvalid(maxHeight)) {
+            throw new ParseException("Parsed dimensions must be in [0, " + PIXEL_MAX + "]");
+        }
+
+        mType = type;
+        mMinWidth = minWidth;
+        mMinHeight = minHeight;
+        mMaxWidth = maxWidth;
+        mMaxHeight = maxHeight;
+    }
+
+    public int getType() {
+        return mType;
+    }
+
+    public int getMinWidth() {
+        return mMinWidth;
+    }
+
+    public int getMaxWidth() {
+        return mMaxWidth;
+    }
+
+    public int getMinHeight() {
+        return mMinHeight;
+    }
+
+    public int getMaxHeight() {
+        return mMaxHeight;
+    }
+
+    /**
+     * Determines the type of the pixel string by counting the number of '*' delimiters in the
+     * string.
+     *
+     * Note that the overall maximum size of any pixel string is 23 characters in length due to the
+     * max size of each dimension
+     *
+     * @return The corresponding type we should assume the given pixel string is
+     */
+    private static int determinePixelType(String pixel) {
+        if (pixel == null || pixel.length() > 23) return TYPE_UNKNOWN;
+        int delimCount = 0;
+        for (char c : pixel.toCharArray()) {
+            if (c == '*') delimCount++;
+        }
+        return delimCount > 0 && delimCount <= 3 ? delimCount : TYPE_UNKNOWN;
+    }
+
+    protected static boolean isDimensionInvalid(int dimension) {
+        return dimension < 0 || dimension > PIXEL_MAX;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (o == this) return true;
+        if (!(o instanceof BipPixel)) return false;
+
+        BipPixel p = (BipPixel) o;
+        return p.getType() == getType()
+                && p.getMinWidth() == getMinWidth()
+                && p.getMaxWidth() == getMaxWidth()
+                && p.getMinHeight() == getMinHeight()
+                && p.getMaxHeight() == getMaxHeight();
+    }
+
+    @Override
+    public String toString() {
+        String s = null;
+        switch (mType) {
+            case TYPE_FIXED:
+                s = mMaxWidth + "*" + mMaxHeight;
+                break;
+            case TYPE_RESIZE_MODIFIED_ASPECT_RATIO:
+                s = mMinWidth + "*" + mMinHeight + "-" + mMaxWidth + "*" + mMaxHeight;
+                break;
+            case TYPE_RESIZE_FIXED_ASPECT_RATIO:
+                s = mMinWidth + "**-" + mMaxWidth + "*" + mMaxHeight;
+                break;
+        }
+        return s;
+    }
+}
diff --git a/src/com/android/bluetooth/avrcpcontroller/bip/BipRequest.java b/src/com/android/bluetooth/avrcpcontroller/bip/BipRequest.java
new file mode 100644
index 0000000..dd2083c
--- /dev/null
+++ b/src/com/android/bluetooth/avrcpcontroller/bip/BipRequest.java
@@ -0,0 +1,187 @@
+/*
+ * Copyright (C) 2019 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.bluetooth.avrcpcontroller;
+
+import android.util.Log;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import javax.obex.ClientOperation;
+import javax.obex.ClientSession;
+import javax.obex.HeaderSet;
+import javax.obex.ResponseCodes;
+
+/**
+ * This is a base class for implementing AVRCP Controller Basic Image Profile (BIP) requests
+ */
+abstract class BipRequest {
+    private static final String TAG = "avrcpcontroller.BipRequest";
+    private static final boolean DBG = Log.isLoggable(TAG, Log.DEBUG);
+
+    // User defined OBEX header identifiers
+    protected static final byte HEADER_ID_IMG_HANDLE = 0x30;
+    protected static final byte HEADER_ID_IMG_DESCRIPTOR = 0x71;
+
+    // Request types
+    public static final int TYPE_GET_IMAGE_PROPERTIES = 0;
+    public static final int TYPE_GET_IMAGE = 1;
+
+    protected HeaderSet mHeaderSet;
+    protected ClientOperation mOperation = null;
+    protected int mResponseCode;
+
+    BipRequest() {
+        mHeaderSet = new HeaderSet();
+        mResponseCode = -1;
+    }
+
+    /**
+     * A function that returns the type of the request.
+     *
+     * Used to determine type instead of using 'instanceof'
+     */
+    public abstract int getType();
+
+    /**
+     * A single point of entry for kicking off a AVRCP BIP request.
+     *
+     * Child classes are expected to implement this interface, filling in the details of the request
+     * (headers, operation type, error handling, etc).
+     */
+    public abstract void execute(ClientSession session) throws IOException;
+
+    /**
+     * A generica GET operation, providing overridable hooks to read response headers and content.
+     */
+    protected void executeGet(ClientSession session) throws IOException {
+        debug("Exeucting GET");
+        setOperation(null);
+        try {
+            ClientOperation operation = (ClientOperation) session.get(mHeaderSet);
+            setOperation(operation);
+            operation.setGetFinalFlag(true);
+            operation.continueOperation(true, false);
+            readResponseHeaders(operation.getReceivedHeader());
+            InputStream inputStream = operation.openInputStream();
+            readResponse(inputStream);
+            inputStream.close();
+            operation.close();
+            mResponseCode = operation.getResponseCode();
+        } catch (IOException e) {
+            mResponseCode = ResponseCodes.OBEX_HTTP_INTERNAL_ERROR;
+            error("GET threw an exeception: " + e);
+            throw e;
+        }
+        debug("GET final response code is '" + mResponseCode + "'");
+    }
+
+    /**
+     * A generica PUT operation, providing overridable hooks to read response headers.
+     */
+    protected void executePut(ClientSession session, byte[] body) throws IOException {
+        debug("Exeucting PUT");
+        setOperation(null);
+        mHeaderSet.setHeader(HeaderSet.LENGTH, Long.valueOf(body.length));
+        try {
+            ClientOperation operation = (ClientOperation) session.put(mHeaderSet);
+            setOperation(operation);
+            DataOutputStream outputStream = mOperation.openDataOutputStream();
+            outputStream.write(body);
+            outputStream.close();
+            readResponseHeaders(operation.getReceivedHeader());
+            operation.close();
+            mResponseCode = operation.getResponseCode();
+        } catch (IOException e) {
+            mResponseCode = ResponseCodes.OBEX_HTTP_INTERNAL_ERROR;
+            error("PUT threw an exeception: " + e);
+            throw e;
+        }
+        debug("PUT final response code is '" + mResponseCode + "'");
+    }
+
+    /**
+     * Determine if the request was a success
+     *
+     * @return True if the request was successful, false otherwise
+     */
+    public final boolean isSuccess() {
+        return (mResponseCode == ResponseCodes.OBEX_HTTP_OK);
+    }
+
+    /**
+     * Get the actual response code associated with the request
+     *
+     * @return The response code as in integer
+     */
+    public final int getResponseCode() {
+        return mResponseCode;
+    }
+
+    /**
+     * A callback for subclasses to add logic to make determinations against the content of the
+     * returned headers.
+     */
+    protected void readResponseHeaders(HeaderSet headerset) {
+        /* nothing here by default */
+    }
+
+    /**
+     * A callback for subclasses to add logic to make determinations against the content of the
+     * returned response body.
+     */
+    protected void readResponse(InputStream stream) throws IOException {
+        /* nothing here by default */
+    }
+
+    private synchronized ClientOperation getOperation() {
+        return mOperation;
+    }
+
+    private synchronized void setOperation(ClientOperation operation) {
+        mOperation = operation;
+    }
+
+    @Override
+    public String toString() {
+        return TAG + " (type: " + getType() + ", mResponseCode: " + mResponseCode + ")";
+    }
+
+    /**
+     * Print to debug if debug is enabled for this class
+     */
+    protected void debug(String msg) {
+        if (DBG) {
+            Log.d(TAG, msg);
+        }
+    }
+
+    /**
+     * Print to warn
+     */
+    protected void warn(String msg) {
+        Log.w(TAG, msg);
+    }
+
+    /**
+     * Print to error
+     */
+    protected void error(String msg) {
+        Log.e(TAG, msg);
+    }
+}
diff --git a/src/com/android/bluetooth/avrcpcontroller/bip/BipTransformation.java b/src/com/android/bluetooth/avrcpcontroller/bip/BipTransformation.java
new file mode 100644
index 0000000..9922f61
--- /dev/null
+++ b/src/com/android/bluetooth/avrcpcontroller/bip/BipTransformation.java
@@ -0,0 +1,181 @@
+/*
+ * Copyright (C) 2019 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.bluetooth.avrcpcontroller;
+
+import android.util.Log;
+
+import java.util.HashSet;
+
+/**
+ * Represents the set of possible transformations available for a variant of an image to get the
+ * image to a particular pixel size.
+ *
+ * The transformations supported by BIP v1.2.1 include:
+ *   - Stretch
+ *   - Fill
+ *   - Crop
+ *
+ * Example in an image properties/format:
+ *   <variant encoding=“GIF” pixel=“80*60-640*480” transformation="stretch fill"/>
+ *   <variant encoding=“GIF” pixel=“80*60-640*480” transformation="fill"/>
+ *   <variant encoding=“GIF” pixel=“80*60-640*480” transformation="stretch fill crop"/>
+ *
+ * Example in an image descriptor:
+ *   <image-descriptor version=“1.0”>
+ *   <image encoding=“JPEG” pixel=“1280*960” size=“500000” transformation="stretch"/>
+ *   </image-descriptor>
+ */
+public class BipTransformation {
+    private static final String TAG = "avrcpcontroller.BipTransformation";
+
+    public static final int UNKNOWN = -1;
+    public static final int STRETCH = 0;
+    public static final int FILL = 1;
+    public static final int CROP = 2;
+
+    public final HashSet<Integer> mSupportedTransformations = new HashSet<Integer>(3);
+
+    /**
+     * Create an empty set of BIP Transformations
+     */
+    public BipTransformation() {
+    }
+
+    /**
+     * Create a set of BIP Transformations from an attribute value from an Image Format string
+     */
+    public BipTransformation(String transformations) {
+        if (transformations == null) return;
+
+        transformations = transformations.trim().toLowerCase();
+        String[] tokens = transformations.split(" ");
+        for (String token : tokens) {
+            switch (token) {
+                case "stretch":
+                    addTransformation(STRETCH);
+                    break;
+                case "fill":
+                    addTransformation(FILL);
+                    break;
+                case "crop":
+                    addTransformation(CROP);
+                    break;
+                default:
+                    Log.e(TAG, "Found unknown transformation '" + token + "'");
+                    break;
+            }
+        }
+    }
+
+    /**
+     * Create a set of BIP Transformations from a single supported transformation
+     */
+    public BipTransformation(int transformation) {
+        addTransformation(transformation);
+    }
+
+    /**
+     * Create a set of BIP Transformations from a set of supported transformations
+     */
+    public BipTransformation(int[] transformations) {
+        for (int transformation : transformations) {
+            addTransformation(transformation);
+        }
+    }
+
+    /**
+     * Add a supported Transformation
+     *
+     * @param transformation - The transformation you with to support
+     */
+    public void addTransformation(int transformation) {
+        if (!isValid(transformation)) {
+            throw new IllegalArgumentException("Invalid transformation ID '" + transformation
+                    + "'");
+        }
+        mSupportedTransformations.add(transformation);
+    }
+
+    /**
+     * Remove a supported Transformation
+     *
+     * @param transformation - The transformation you with to remove support for
+     */
+    public void removeTransformation(int transformation) {
+        if (!isValid(transformation)) {
+            throw new IllegalArgumentException("Invalid transformation ID '" + transformation
+                    + "'");
+        }
+        mSupportedTransformations.remove(transformation);
+    }
+
+    /**
+     * Determine if a given transformations is valid
+     *
+     * @param transformation The integer encoding ID of the transformation. Should be one of the
+     *                       BipTransformation.* constants, but doesn't *have* to be
+     * @return True if the transformation constant is valid, False otherwise
+     */
+    private boolean isValid(int transformation) {
+        return transformation >= STRETCH && transformation <= CROP;
+    }
+
+    /**
+     * Determine if this set of transformations supports a desired transformation
+     *
+     * @param transformation The ID of the desired transformation, STRETCH, FILL, or CROP
+     * @return True if this set supports the transformation, False otherwise
+     */
+    public boolean isSupported(int transformation) {
+        return mSupportedTransformations.contains(transformation);
+    }
+
+    /**
+     * Determine if this object supports any transformations at all
+     *
+     * @return True if any valid transformations are supported, False otherwise
+     */
+    public boolean supportsAny() {
+        return !mSupportedTransformations.isEmpty();
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (o == this) return true;
+        if (o == null && !supportsAny()) return true;
+        if (!(o instanceof BipTransformation)) return false;
+
+        BipTransformation t = (BipTransformation) o;
+        return mSupportedTransformations.equals(t.mSupportedTransformations);
+    }
+
+    @Override
+    public String toString() {
+        if (!supportsAny()) return null;
+        String transformations = "";
+        if (isSupported(STRETCH)) {
+            transformations += "stretch ";
+        }
+        if (isSupported(FILL)) {
+            transformations += "fill ";
+        }
+        if (isSupported(CROP)) {
+            transformations += "crop ";
+        }
+        return transformations.trim();
+    }
+}
diff --git a/src/com/android/bluetooth/avrcpcontroller/bip/ParseException.java b/src/com/android/bluetooth/avrcpcontroller/bip/ParseException.java
new file mode 100644
index 0000000..8dbb736
--- /dev/null
+++ b/src/com/android/bluetooth/avrcpcontroller/bip/ParseException.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2019 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.bluetooth.avrcpcontroller;
+
+/**
+ * Thrown when has parsing.
+ */
+public class ParseException extends RuntimeException {
+    public ParseException(String msg) {
+        super(msg);
+    }
+}
diff --git a/src/com/android/bluetooth/avrcpcontroller/bip/RequestGetImage.java b/src/com/android/bluetooth/avrcpcontroller/bip/RequestGetImage.java
new file mode 100644
index 0000000..42b376c
--- /dev/null
+++ b/src/com/android/bluetooth/avrcpcontroller/bip/RequestGetImage.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2019 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.bluetooth.avrcpcontroller;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import javax.obex.ClientSession;
+import javax.obex.HeaderSet;
+
+/**
+ * This implements a GetImage request, allowing a user to retrieve an image from the remote device
+ * with a specified format, encoding, etc.
+ */
+public class RequestGetImage extends BipRequest {
+    // Expected inputs
+    private final String mImageHandle;
+    private final BipImageDescriptor mImageDescriptor;
+
+    // Expected return type
+    private static final String TYPE = "x-bt/img-img";
+    private BipImage mImage = null;
+
+    public RequestGetImage(String imageHandle, BipImageDescriptor descriptor) {
+        mHeaderSet = new HeaderSet();
+        mResponseCode = -1;
+
+        mImageHandle = imageHandle;
+        mImageDescriptor = descriptor;
+
+        debug("GetImage - handle: " + mImageHandle + ", descriptor: "
+                + mImageDescriptor.toString());
+
+        mHeaderSet.setHeader(HeaderSet.TYPE, TYPE);
+        mHeaderSet.setHeader(HEADER_ID_IMG_HANDLE, mImageHandle);
+        mHeaderSet.setHeader(HEADER_ID_IMG_DESCRIPTOR, mImageDescriptor.serialize());
+    }
+
+    @Override
+    public int getType() {
+        return TYPE_GET_IMAGE;
+    }
+
+    @Override
+    public void execute(ClientSession session) throws IOException {
+        executeGet(session);
+    }
+
+    @Override
+    protected void readResponse(InputStream stream) throws IOException {
+        mImage = new BipImage(mImageHandle, stream);
+        debug("Response GetImage - handle:" + mImageHandle + ", image: " + mImage);
+    }
+
+    /**
+     * Get the image handle associated with this request
+     *
+     * @return image handle used with this request
+     */
+    public String getImageHandle() {
+        return mImageHandle;
+    }
+
+    /**
+     * Get the downloaded image sent from the remote device
+     *
+     * @return A BipImage object containing the downloaded image Bitmap
+     */
+    public BipImage getImage() {
+        return mImage;
+    }
+}
diff --git a/src/com/android/bluetooth/avrcpcontroller/bip/RequestGetImageProperties.java b/src/com/android/bluetooth/avrcpcontroller/bip/RequestGetImageProperties.java
new file mode 100644
index 0000000..54813cc
--- /dev/null
+++ b/src/com/android/bluetooth/avrcpcontroller/bip/RequestGetImageProperties.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2019 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.bluetooth.avrcpcontroller;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import javax.obex.ClientSession;
+import javax.obex.HeaderSet;
+
+/**
+ * This implements a GetImageProperties request, allowing a user to retrieve information regarding
+ * the image formats, encodings, etc. available for an image.
+ */
+public class RequestGetImageProperties extends BipRequest {
+    // Expected inputs
+    private String mImageHandle = null;
+
+    // Expected return type
+    private static final String TYPE = "x-bt/img-properties";
+    private BipImageProperties mImageProperties = null;
+
+    public RequestGetImageProperties(String imageHandle) {
+        mHeaderSet = new HeaderSet();
+        mResponseCode = -1;
+        mImageHandle = imageHandle;
+
+        debug("GetImageProperties - handle: " + mImageHandle);
+
+        mHeaderSet.setHeader(HeaderSet.TYPE, TYPE);
+        mHeaderSet.setHeader(HEADER_ID_IMG_HANDLE, mImageHandle);
+    }
+
+    @Override
+    public int getType() {
+        return TYPE_GET_IMAGE_PROPERTIES;
+    }
+
+    @Override
+    public void execute(ClientSession session) throws IOException {
+        executeGet(session);
+    }
+
+    @Override
+    protected void readResponse(InputStream stream) throws IOException {
+        try {
+            mImageProperties = new BipImageProperties(stream);
+            debug("Response GetImageProperties - handle: " + mImageHandle + ", properties: "
+                    + mImageProperties.toString());
+        } catch (ParseException e) {
+            error("Failed to parse incoming properties object");
+            mImageProperties = null;
+        }
+    }
+
+    /**
+     * Get the image handle associated with this request
+     *
+     * @return image handle used with this request
+     */
+    public String getImageHandle() {
+        return mImageHandle;
+    }
+
+    /**
+     * Get the requested set of image properties sent from the remote device
+     *
+     * @return A BipImageProperties object
+     */
+    public BipImageProperties getImageProperties() {
+        return mImageProperties;
+    }
+}
