Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7a3efdb9 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Update output chooser for calls"

parents 2537932f 5daa4727
Loading
Loading
Loading
Loading
+12 −2
Original line number Diff line number Diff line
@@ -14,7 +14,7 @@
     See the License for the specific language governing permissions and
     limitations under the License.
-->
<!-- extends FrameLayout -->
<!-- extends LinearLayout -->
<com.android.systemui.volume.OutputChooserLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:sysui="http://schemas.android.com/apk/res-auto"
@@ -23,8 +23,17 @@
    android:minHeight="320dp"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="20dp" >

    <TextView
        android:id="@+id/title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textDirection="locale"
        android:textAppearance="@style/TextAppearance.QS.DetailHeader"
        android:layout_marginBottom="20dp" />

    <com.android.systemui.qs.AutoSizingList
        android:id="@android:id/list"
        android:layout_width="match_parent"
@@ -42,9 +51,10 @@
        android:orientation="vertical">

        <TextView
            android:id="@android:id/title"
            android:id="@+id/empty_text"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textDirection="locale"
            android:layout_marginTop="20dp"
            android:textAppearance="@style/TextAppearance.QS.DetailEmpty"/>
    </LinearLayout>
+1 −0
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@
        android:layout_height="@dimen/qs_detail_item_icon_size"
        android:layout_marginStart="@dimen/qs_detail_item_icon_marginStart"
        android:layout_marginEnd="@dimen/qs_detail_item_icon_marginEnd"
        android:background="?android:selectableItemBackgroundBorderless"
        android:tint="?android:attr/textColorPrimary"/>

    <LinearLayout
+51 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 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.systemui.volume;

import android.support.v7.media.MediaRouteSelector;
import android.support.v7.media.MediaRouter;

import java.util.List;

/**
 * Wrapper for final class MediaRouter, for testing.
 */
public class MediaRouterWrapper {

    private final MediaRouter mRouter;

    public MediaRouterWrapper(MediaRouter router)
    {
        mRouter = router;
    }

    public void addCallback(MediaRouteSelector selector, MediaRouter.Callback callback, int flags) {
        mRouter.addCallback(selector, callback, flags);
    }

    public void removeCallback(MediaRouter.Callback callback) {
        mRouter.removeCallback(callback);
    }

    public void unselect(int reason) {
        mRouter.unselect(reason);
    }

    public List<MediaRouter.RouteInfo> getRoutes() {
        return mRouter.getRoutes();
    }
}
 No newline at end of file
+55 −37
Original line number Diff line number Diff line
/*
 * Copyright (C) 2015 The Android Open Source Project
 * Copyright (C) 2017 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.
@@ -40,6 +40,7 @@ import android.os.SystemClock;
import android.support.v7.media.MediaControlIntent;
import android.support.v7.media.MediaRouteSelector;
import android.support.v7.media.MediaRouter;
import android.telecom.TelecomManager;
import android.util.Log;
import android.util.Pair;

@@ -54,7 +55,6 @@ import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

@@ -65,15 +65,17 @@ public class OutputChooserDialog extends SystemUIDialog
    private static final int MAX_DEVICES = 10;

    private static final long UPDATE_DELAY_MS = 300L;
    static final int MSG_UPDATE_ITEMS = 1;
    private static final int MSG_UPDATE_ITEMS = 1;

    private final Context mContext;
    private final BluetoothController mController;
    private final WifiManager mWifiManager;
    private final BluetoothController mBluetoothController;
    private WifiManager mWifiManager;
    private OutputChooserLayout mView;
    private final MediaRouter mRouter;
    private final MediaRouterWrapper mRouter;
    private final MediaRouterCallback mRouterCallback;
    private long mLastUpdateTime;
    private boolean mIsInCall;
    protected boolean isAttached;

    private final MediaRouteSelector mRouteSelector;
    private Drawable mDefaultIcon;
@@ -81,12 +83,14 @@ public class OutputChooserDialog extends SystemUIDialog
    private Drawable mSpeakerIcon;
    private Drawable mSpeakerGroupIcon;

    public OutputChooserDialog(Context context) {
    public OutputChooserDialog(Context context, MediaRouterWrapper router) {
        super(context);
        mContext = context;
        mController = Dependency.get(BluetoothController.class);
        mBluetoothController = Dependency.get(BluetoothController.class);
        mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
        mRouter = MediaRouter.getInstance(context);
        TelecomManager tm = (TelecomManager) context.getSystemService(Context.TELECOM_SERVICE);
        mIsInCall = tm.isInCall();
        mRouter = router;
        mRouterCallback = new MediaRouterCallback();
        mRouteSelector = new MediaRouteSelector.Builder()
                .addControlCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK)
@@ -96,27 +100,38 @@ public class OutputChooserDialog extends SystemUIDialog
        context.registerReceiver(mReceiver, filter);
    }

    protected void setIsInCall(boolean inCall) {
        mIsInCall = inCall;
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.output_chooser);
        setCanceledOnTouchOutside(true);
        setOnDismissListener(this::onDismiss);
        setTitle(R.string.output_title);

        mView = findViewById(R.id.output_chooser);
        mView.setCallback(this);

        if (mIsInCall) {
            mView.setTitle(R.string.output_calls_title);
        } else {
            mView.setTitle(R.string.output_title);
        }

        mDefaultIcon = mContext.getDrawable(R.drawable.ic_cast);
        mTvIcon = mContext.getDrawable(R.drawable.ic_tv);
        mSpeakerIcon = mContext.getDrawable(R.drawable.ic_speaker);
        mSpeakerGroupIcon = mContext.getDrawable(R.drawable.ic_speaker_group);

        final boolean wifiOff = !mWifiManager.isWifiEnabled();
        final boolean btOff = !mController.isBluetoothEnabled();
        if (wifiOff || btOff) {
        final boolean btOff = !mBluetoothController.isBluetoothEnabled();
        if (wifiOff && btOff) {
            mView.setEmptyState(getDisabledServicesMessage(wifiOff, btOff));
        }
        // time out after 5 seconds
        mView.postDelayed(() -> updateItems(true), 5000);
    }

    protected void cleanUp() {}
@@ -131,15 +146,19 @@ public class OutputChooserDialog extends SystemUIDialog
    public void onAttachedToWindow() {
        super.onAttachedToWindow();

        if (!mIsInCall) {
            mRouter.addCallback(mRouteSelector, mRouterCallback,
                    MediaRouter.CALLBACK_FLAG_PERFORM_ACTIVE_SCAN);
        mController.addCallback(mCallback);
        }
        mBluetoothController.addCallback(mCallback);
        isAttached = true;
    }

    @Override
    public void onDetachedFromWindow() {
        isAttached = false;
        mRouter.removeCallback(mRouterCallback);
        mController.removeCallback(mCallback);
        mBluetoothController.removeCallback(mCallback);
        super.onDetachedFromWindow();
    }

@@ -154,9 +173,8 @@ public class OutputChooserDialog extends SystemUIDialog
        if (item == null || item.tag == null) return;
        if (item.deviceType == OutputChooserLayout.Item.DEVICE_TYPE_BT) {
            final CachedBluetoothDevice device = (CachedBluetoothDevice) item.tag;
            if (device != null && device.getMaxConnectionState()
                    == BluetoothProfile.STATE_DISCONNECTED) {
                mController.connect(device);
            if (device.getMaxConnectionState() == BluetoothProfile.STATE_DISCONNECTED) {
                mBluetoothController.connect(device);
            }
        } else if (item.deviceType == OutputChooserLayout.Item.DEVICE_TYPE_MEDIA_ROUTER) {
            final MediaRouter.RouteInfo route = (MediaRouter.RouteInfo) item.tag;
@@ -171,18 +189,16 @@ public class OutputChooserDialog extends SystemUIDialog
        if (item == null || item.tag == null) return;
        if (item.deviceType == OutputChooserLayout.Item.DEVICE_TYPE_BT) {
            final CachedBluetoothDevice device = (CachedBluetoothDevice) item.tag;
            if (device != null) {
                mController.disconnect(device);
            }
            mBluetoothController.disconnect(device);
        } else if (item.deviceType == OutputChooserLayout.Item.DEVICE_TYPE_MEDIA_ROUTER) {
            mRouter.unselect(UNSELECT_REASON_DISCONNECTED);
        }
    }

    private void updateItems() {
    private void updateItems(boolean timeout) {
        if (SystemClock.uptimeMillis() - mLastUpdateTime < UPDATE_DELAY_MS) {
            mHandler.removeMessages(MSG_UPDATE_ITEMS);
            mHandler.sendMessageAtTime(mHandler.obtainMessage(MSG_UPDATE_ITEMS),
            mHandler.sendMessageAtTime(mHandler.obtainMessage(MSG_UPDATE_ITEMS, timeout),
                    mLastUpdateTime + UPDATE_DELAY_MS);
            return;
        }
@@ -194,14 +210,16 @@ public class OutputChooserDialog extends SystemUIDialog
        addBluetoothDevices(items);

        // Add remote displays
        if (!mIsInCall) {
            addRemoteDisplayRoutes(items);
        }

        Collections.sort(items, ItemComparator.sInstance);
        items.sort(ItemComparator.sInstance);

        if (items.size() == 0) {
        if (items.size() == 0 && timeout) {
            String emptyMessage = mContext.getString(R.string.output_none_found);
            final boolean wifiOff = !mWifiManager.isWifiEnabled();
            final boolean btOff = !mController.isBluetoothEnabled();
            final boolean btOff = !mBluetoothController.isBluetoothEnabled();
            if (wifiOff || btOff) {
                emptyMessage = getDisabledServicesMessage(wifiOff, btOff);
            }
@@ -219,12 +237,12 @@ public class OutputChooserDialog extends SystemUIDialog
    }

    private void addBluetoothDevices(List<OutputChooserLayout.Item> items) {
        final Collection<CachedBluetoothDevice> devices = mController.getDevices();
        final Collection<CachedBluetoothDevice> devices = mBluetoothController.getDevices();
        if (devices != null) {
            int connectedDevices = 0;
            int count = 0;
            for (CachedBluetoothDevice device : devices) {
                if (mController.getBondState(device) == BluetoothDevice.BOND_NONE) continue;
                if (mBluetoothController.getBondState(device) == BluetoothDevice.BOND_NONE) continue;
                final int majorClass = device.getBtClass().getMajorDeviceClass();
                if (majorClass != BluetoothClass.Device.Major.AUDIO_VIDEO
                        && majorClass != BluetoothClass.Device.Major.UNCATEGORIZED) {
@@ -328,22 +346,22 @@ public class OutputChooserDialog extends SystemUIDialog
    private final class MediaRouterCallback extends MediaRouter.Callback {
        @Override
        public void onRouteAdded(MediaRouter router, MediaRouter.RouteInfo info) {
            updateItems();
            updateItems(false);
        }

        @Override
        public void onRouteRemoved(MediaRouter router, MediaRouter.RouteInfo info) {
            updateItems();
            updateItems(false);
        }

        @Override
        public void onRouteChanged(MediaRouter router, MediaRouter.RouteInfo info) {
            updateItems();
            updateItems(false);
        }

        @Override
        public void onRouteSelected(MediaRouter router, MediaRouter.RouteInfo route) {
            dismiss();
            updateItems(false);
        }
    }

@@ -361,12 +379,12 @@ public class OutputChooserDialog extends SystemUIDialog
    private final BluetoothController.Callback mCallback = new BluetoothController.Callback() {
        @Override
        public void onBluetoothStateChange(boolean enabled) {
            updateItems();
            updateItems(false);
        }

        @Override
        public void onBluetoothDevicesChanged() {
            updateItems();
            updateItems(false);
        }
    };

@@ -393,7 +411,7 @@ public class OutputChooserDialog extends SystemUIDialog
        public void handleMessage(Message message) {
            switch (message.what) {
                case MSG_UPDATE_ITEMS:
                    updateItems();
                    updateItems((Boolean) message.obj);
                    break;
            }
        }
+13 −15
Original line number Diff line number Diff line
@@ -29,8 +29,8 @@ import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.android.systemui.FontSizeUtils;
@@ -40,11 +40,10 @@ import com.android.systemui.qs.AutoSizingList;
/**
 * Limited height list of devices.
 */
public class OutputChooserLayout extends FrameLayout {
public class OutputChooserLayout extends LinearLayout {
    private static final String TAG = "OutputChooserLayout";
    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);

    private final int mQsDetailIconOverlaySize;
    private final Context mContext;
    private final H mHandler = new H();
    private final Adapter mAdapter = new Adapter();
@@ -55,6 +54,7 @@ public class OutputChooserLayout extends FrameLayout {
    private AutoSizingList mItemList;
    private View mEmpty;
    private TextView mEmptyText;
    private TextView mTitle;

    private Item[] mItems;

@@ -62,8 +62,6 @@ public class OutputChooserLayout extends FrameLayout {
        super(context, attrs);
        mContext = context;
        mTag = TAG;
        mQsDetailIconOverlaySize = (int) getResources().getDimension(
                R.dimen.qs_detail_icon_overlay_size);
    }

    @Override
@@ -74,7 +72,8 @@ public class OutputChooserLayout extends FrameLayout {
        mItemList.setAdapter(mAdapter);
        mEmpty = findViewById(android.R.id.empty);
        mEmpty.setVisibility(GONE);
        mEmptyText = mEmpty.findViewById(android.R.id.title);
        mEmptyText = mEmpty.findViewById(R.id.empty_text);
        mTitle = findViewById(R.id.title);
    }

    @Override
@@ -84,17 +83,21 @@ public class OutputChooserLayout extends FrameLayout {
        int count = mItemList.getChildCount();
        for (int i = 0; i < count; i++) {
            View item = mItemList.getChildAt(i);
            FontSizeUtils.updateFontSize(item, android.R.id.title,
            FontSizeUtils.updateFontSize(item, R.id.empty_text,
                    R.dimen.qs_detail_item_primary_text_size);
            FontSizeUtils.updateFontSize(item, android.R.id.summary,
                    R.dimen.qs_detail_item_secondary_text_size);
            FontSizeUtils.updateFontSize(item, android.R.id.title,
                    R.dimen.qs_detail_header_text_size);
        }
    }

    public void setTitle(int title) {
            mTitle.setText(title);
    }

    public void setEmptyState(String text) {
        mEmpty.post(() -> {
        mEmptyText.setText(text);
        });
    }

    @Override
@@ -176,11 +179,6 @@ public class OutputChooserLayout extends FrameLayout {
            } else {
                iv.setImageResource(item.iconResId);
            }
            iv.getOverlay().clear();
            if (item.overlay != null) {
                item.overlay.setBounds(0, 0, mQsDetailIconOverlaySize, mQsDetailIconOverlaySize);
                iv.getOverlay().add(item.overlay);
            }
            final TextView title = view.findViewById(android.R.id.title);
            title.setText(item.line1);
            final TextView summary =  view.findViewById(android.R.id.summary);
Loading