Merge "Implement MediaDevice for seamless transfer"
diff --git a/packages/SettingsLib/Android.bp b/packages/SettingsLib/Android.bp
index 5161344..d1f140f 100644
--- a/packages/SettingsLib/Android.bp
+++ b/packages/SettingsLib/Android.bp
@@ -9,6 +9,7 @@
         "androidx.preference_preference",
         "androidx.appcompat_appcompat",
         "androidx.lifecycle_lifecycle-runtime",
+        "androidx.mediarouter_mediarouter-nodeps",
 
         "SettingsLibHelpUtils",
         "SettingsLibRestrictedLockUtils",
diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml
index 738d729..c9bcd65 100644
--- a/packages/SettingsLib/res/values/strings.xml
+++ b/packages/SettingsLib/res/values/strings.xml
@@ -1133,4 +1133,7 @@
 
     <!-- UI debug setting: opt in to use updated graphics driver? [CHAR LIMIT=100] -->
     <string name="updated_gfx_driver_dev_opt_in_app_summary">Opt in app to use updated graphcis driver in developement</string>
+
+    <!-- Name of the phone device [CHAR LIMIT=NONE] -->
+    <string name="media_transfer_phone_device_name">Phone speaker</string>
 </resources>
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/BluetoothMediaDevice.java b/packages/SettingsLib/src/com/android/settingslib/media/BluetoothMediaDevice.java
new file mode 100644
index 0000000..e535348
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/media/BluetoothMediaDevice.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2018 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.settingslib.media;
+
+import android.content.Context;
+import android.util.Log;
+
+import com.android.settingslib.R;
+import com.android.settingslib.bluetooth.CachedBluetoothDevice;
+
+/**
+ * BluetoothMediaDevice extends MediaDevice to represents Bluetooth device.
+ */
+public class BluetoothMediaDevice extends MediaDevice {
+
+    private static final String TAG = "BluetoothMediaDevice";
+
+    private CachedBluetoothDevice mCachedDevice;
+
+    BluetoothMediaDevice(Context context, CachedBluetoothDevice device) {
+        super(context, MediaDeviceType.TYPE_BLUETOOTH_DEVICE);
+        mCachedDevice = device;
+    }
+
+    @Override
+    public String getName() {
+        return mCachedDevice.getName();
+    }
+
+    @Override
+    public int getIcon() {
+        //TODO(b/117129183): This is not final icon for bluetooth device, just for demo.
+        return R.drawable.ic_bt_headphones_a2dp;
+    }
+
+    @Override
+    public String getId() {
+        return MediaDeviceUtils.getId(mCachedDevice);
+    }
+
+    @Override
+    public void connect() {
+        //TODO(b/117129183): add callback to notify LocalMediaManager connection state.
+        mIsConnected = mCachedDevice.setActive();
+        Log.d(TAG, "connect() device : " + getName() + ", is selected : " + mIsConnected);
+    }
+
+    @Override
+    public void disconnect() {
+        //TODO(b/117129183): disconnected last select device
+        mIsConnected = false;
+    }
+
+    /**
+     * Get current CachedBluetoothDevice
+     */
+    public CachedBluetoothDevice getCachedDevice() {
+        return mCachedDevice;
+    }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaDevice.java b/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaDevice.java
new file mode 100644
index 0000000..498a0fc
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaDevice.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2018 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.settingslib.media;
+
+import android.content.Context;
+
+import androidx.mediarouter.media.MediaRouter;
+
+import com.android.settingslib.R;
+
+/**
+ * InfoMediaDevice extends MediaDevice to represents wifi device.
+ */
+public class InfoMediaDevice extends MediaDevice {
+
+    private static final String TAG = "InfoMediaDevice";
+
+    private MediaRouter.RouteInfo mRouteInfo;
+
+    InfoMediaDevice(Context context, MediaRouter.RouteInfo info) {
+        super(context, MediaDeviceType.TYPE_CAST_DEVICE);
+        mRouteInfo = info;
+    }
+
+    @Override
+    public String getName() {
+        return mRouteInfo.getName();
+    }
+
+    @Override
+    public int getIcon() {
+        //TODO(b/117129183): This is not final icon for cast device, just for demo.
+        return R.drawable.ic_settings_print;
+    }
+
+    @Override
+    public String getId() {
+        return MediaDeviceUtils.getId(mRouteInfo);
+    }
+
+    @Override
+    public void connect() {
+        //TODO(b/117129183): use MediaController2 to transfer media
+        mIsConnected = true;
+    }
+
+    @Override
+    public void disconnect() {
+        //TODO(b/117129183): disconnected last select device
+        mIsConnected = false;
+    }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java b/packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java
new file mode 100644
index 0000000..6c536f0
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2018 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.settingslib.media;
+
+import android.content.Context;
+
+import androidx.annotation.IntDef;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * MediaDevice represents a media device(such like Bluetooth device, cast device and phone device).
+ */
+public abstract class MediaDevice {
+
+    private static final String TAG = "MediaDevice";
+
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef({MediaDeviceType.TYPE_BLUETOOTH_DEVICE,
+            MediaDeviceType.TYPE_CAST_DEVICE,
+            MediaDeviceType.TYPE_PHONE_DEVICE})
+    public @interface MediaDeviceType {
+        int TYPE_BLUETOOTH_DEVICE = 1;
+        int TYPE_CAST_DEVICE = 2;
+        int TYPE_PHONE_DEVICE = 3;
+    }
+
+    protected boolean mIsConnected = false;
+    protected Context mContext;
+    protected int mType;
+
+    MediaDevice(Context context, @MediaDeviceType int type) {
+        mType = type;
+        mContext = context;
+    }
+
+    /**
+     * Check the MediaDevice is be connected to transfer.
+     *
+     * @return true if the MediaDevice is be connected to transfer, false otherwise.
+     */
+    protected boolean isConnected() {
+        return mIsConnected;
+    }
+
+    /**
+     * Get name from MediaDevice.
+     *
+     * @return name of MediaDevice.
+     */
+    public abstract String getName();
+
+    /**
+     * Get resource id of MediaDevice.
+     *
+     * @return resource id of MediaDevice.
+     */
+    public abstract int getIcon();
+
+    /**
+     * Get unique ID that represent MediaDevice
+     * @return unique id of MediaDevice
+     */
+    public abstract String getId();
+
+    /**
+     * Transfer MediaDevice for media
+     */
+    public abstract void connect();
+
+    /**
+     * Stop transfer MediaDevice
+     */
+    public abstract void disconnect();
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/MediaDeviceUtils.java b/packages/SettingsLib/src/com/android/settingslib/media/MediaDeviceUtils.java
new file mode 100644
index 0000000..060e9ad
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/media/MediaDeviceUtils.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2018 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.settingslib.media;
+
+import androidx.mediarouter.media.MediaRouter;
+
+import com.android.settingslib.bluetooth.CachedBluetoothDevice;
+
+/**
+ * MediaDeviceUtils provides utility function for MediaDevice
+ */
+public class MediaDeviceUtils {
+
+    /**
+     * Use CachedBluetoothDevice address to represent unique id
+     *
+     * @param cachedDevice the CachedBluetoothDevice
+     * @return CachedBluetoothDevice address
+     */
+    public static String getId(CachedBluetoothDevice cachedDevice) {
+        return cachedDevice.getAddress();
+    }
+
+    /**
+     * Use RouteInfo id to represent unique id
+     *
+     * @param route the RouteInfo
+     * @return RouteInfo id
+     */
+    public static String getId(MediaRouter.RouteInfo route) {
+        return route.getId();
+    }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/PhoneMediaDevice.java b/packages/SettingsLib/src/com/android/settingslib/media/PhoneMediaDevice.java
new file mode 100644
index 0000000..5e49d6b
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/media/PhoneMediaDevice.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2018 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.settingslib.media;
+
+import android.content.Context;
+import android.util.Log;
+
+import com.android.settingslib.R;
+import com.android.settingslib.bluetooth.A2dpProfile;
+import com.android.settingslib.bluetooth.HearingAidProfile;
+import com.android.settingslib.bluetooth.LocalBluetoothManager;
+import com.android.settingslib.bluetooth.LocalBluetoothProfileManager;
+
+/**
+ * PhoneMediaDevice extends MediaDevice to represents Phone device.
+ */
+public class PhoneMediaDevice extends MediaDevice {
+
+    private static final String TAG = "PhoneMediaDevice";
+
+    public static final String ID = "phone_media_device_id_1";
+
+    private LocalBluetoothProfileManager mProfileManager;
+    private LocalBluetoothManager mLocalBluetoothManager;
+
+    PhoneMediaDevice(Context context, LocalBluetoothManager localBluetoothManager) {
+        super(context, MediaDeviceType.TYPE_PHONE_DEVICE);
+
+        mLocalBluetoothManager = localBluetoothManager;
+        mProfileManager = mLocalBluetoothManager.getProfileManager();
+    }
+
+    @Override
+    public String getName() {
+        return mContext
+                .getString(com.android.settingslib.R.string.media_transfer_phone_device_name);
+    }
+
+    @Override
+    public int getIcon() {
+        //TODO(b/117129183): This is not final icon for phone device, just for demo.
+        return R.drawable.ic_bt_cellphone;
+    }
+
+    @Override
+    public String getId() {
+        return ID;
+    }
+
+    @Override
+    public void connect() {
+        final HearingAidProfile hapProfile = mProfileManager.getHearingAidProfile();
+        final A2dpProfile a2dpProfile = mProfileManager.getA2dpProfile();
+
+        if (hapProfile != null && a2dpProfile != null) {
+            mIsConnected =
+                    hapProfile.setActiveDevice(null) && a2dpProfile.setActiveDevice(null);
+        }
+        Log.d(TAG, "connect() device : " + getName() + ", is selected : " + mIsConnected);
+    }
+
+    @Override
+    public void disconnect() {
+        //TODO(b/117129183): disconnected last select device
+        mIsConnected = false;
+    }
+}