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

Commit e56ba43f authored by Kurt Dresner's avatar Kurt Dresner
Browse files

Update DeviceStateMonitor to watch for changes to projection state instead of car mode.

Bug: 134997071
Bug: 169702986
Test: Code builds, unit tests pass
Change-Id: Id5cb9cb3b5b853da8cd2f994ba0ae32d87baeeb4
parent b5671c10
Loading
Loading
Loading
Loading
+31 −30
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.internal.telephony;

import static android.app.UiModeManager.PROJECTION_TYPE_AUTOMOTIVE;
import static android.hardware.radio.V1_0.DeviceStateType.CHARGING_STATE;
import static android.hardware.radio.V1_0.DeviceStateType.LOW_DATA_EXPECTED;
import static android.hardware.radio.V1_0.DeviceStateType.POWER_SAVE_MODE;
@@ -25,7 +26,6 @@ import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.Configuration;
import android.hardware.display.DisplayManager;
import android.hardware.radio.V1_5.IndicationFilter;
import android.net.ConnectivityManager;
@@ -71,7 +71,7 @@ public class DeviceStateMonitor extends Handler {
    protected static final String TAG = DeviceStateMonitor.class.getSimpleName();

    static final int EVENT_RIL_CONNECTED                = 0;
    static final int EVENT_CAR_MODE_CHANGED             = 1;
    static final int EVENT_AUTOMOTIVE_PROJECTION_STATE_CHANGED = 1;
    @VisibleForTesting
    static final int EVENT_SCREEN_STATE_CHANGED         = 2;
    static final int EVENT_POWER_SAVE_MODE_CHANGED      = 3;
@@ -173,11 +173,11 @@ public class DeviceStateMonitor extends Handler {
    private boolean mIsWifiConnected;

    /**
     * Car mode is on. True means the device is currently connected to Android Auto. This should be
     * handled by mIsScreenOn, but the Android Auto display is private and not accessible by
     * DeviceStateMonitor from DisplayMonitor.
     * Automotive projection is active. True means the device is currently connected to Android
     * Auto. This should be handled by mIsScreenOn, but the Android Auto display is private and not
     * accessible by DeviceStateMonitor from DisplayMonitor.
     */
    private boolean mIsCarModeOn;
    private boolean mIsAutomotiveProjectionActive;

    /**
     * True indicates we should always enable the signal strength reporting from radio.
@@ -248,14 +248,6 @@ public class DeviceStateMonitor extends Handler {
                    msg = obtainMessage(EVENT_TETHERING_STATE_CHANGED);
                    msg.arg1 = isTetheringOn ? 1 : 0;
                    break;
                case UiModeManager.ACTION_ENTER_CAR_MODE_PRIORITIZED:
                    msg = obtainMessage(EVENT_CAR_MODE_CHANGED);
                    msg.arg1 = 1; // car mode on
                    break;
                case UiModeManager.ACTION_EXIT_CAR_MODE_PRIORITIZED:
                    msg = obtainMessage(EVENT_CAR_MODE_CHANGED);
                    msg.arg1 = 0; // car mode off
                    break;
                default:
                    log("Unexpected broadcast intent: " + intent, false);
                    return;
@@ -279,7 +271,7 @@ public class DeviceStateMonitor extends Handler {
        mIsPowerSaveOn = isPowerSaveModeOn();
        mIsCharging = isDeviceCharging();
        mIsScreenOn = isScreenOn();
        mIsCarModeOn = isCarModeOn();
        mIsAutomotiveProjectionActive = isAutomotiveProjectionActive();
        // Assuming tethering is always off after boot up.
        mIsTetheringOn = false;
        mIsLowDataExpected = false;
@@ -289,7 +281,7 @@ public class DeviceStateMonitor extends Handler {
                + ", mIsCharging=" + mIsCharging
                + ", mIsPowerSaveOn=" + mIsPowerSaveOn
                + ", mIsLowDataExpected=" + mIsLowDataExpected
                + ", mIsCarModeOn=" + mIsCarModeOn
                + ", mIsAutomotiveProjectionActive=" + mIsAutomotiveProjectionActive
                + ", mIsWifiConnected=" + mIsWifiConnected
                + ", mIsAlwaysSignalStrengthReportingEnabled="
                + mIsAlwaysSignalStrengthReportingEnabled, false);
@@ -299,8 +291,6 @@ public class DeviceStateMonitor extends Handler {
        filter.addAction(BatteryManager.ACTION_CHARGING);
        filter.addAction(BatteryManager.ACTION_DISCHARGING);
        filter.addAction(ConnectivityManager.ACTION_TETHER_STATE_CHANGED);
        filter.addAction(UiModeManager.ACTION_ENTER_CAR_MODE_PRIORITIZED);
        filter.addAction(UiModeManager.ACTION_EXIT_CAR_MODE_PRIORITIZED);
        mPhone.getContext().registerReceiver(mBroadcastReceiver, filter, null, mPhone);

        mPhone.mCi.registerForRilConnected(this, EVENT_RIL_CONNECTED, null);
@@ -309,6 +299,16 @@ public class DeviceStateMonitor extends Handler {
        ConnectivityManager cm = (ConnectivityManager) phone.getContext().getSystemService(
                Context.CONNECTIVITY_SERVICE);
        cm.registerNetworkCallback(mWifiNetworkRequest, mNetworkCallback);

        UiModeManager umm = (UiModeManager) phone.getContext().getSystemService(
                Context.UI_MODE_SERVICE);
        umm.addOnProjectionStateChangeListener(PROJECTION_TYPE_AUTOMOTIVE,
                phone.getContext().getMainExecutor(),
                (t, pkgs) -> {
                    Message msg = obtainMessage(EVENT_AUTOMOTIVE_PROJECTION_STATE_CHANGED);
                    msg.arg1 = Math.min(pkgs.size(), 1);
                    sendMessage(msg);
                });
    }

    /**
@@ -403,8 +403,8 @@ public class DeviceStateMonitor extends Handler {
        // 1. The device is charging.
        // 2. When the screen is on.
        // 3. When the tethering is on.
        // 4. When car mode (Android Auto) is on.
        return mIsCharging || mIsScreenOn || mIsTetheringOn || mIsCarModeOn;
        // 4. When automotive projection (Android Auto) is on.
        return mIsCharging || mIsScreenOn || mIsTetheringOn || mIsAutomotiveProjectionActive;
    }

    /**
@@ -458,7 +458,7 @@ public class DeviceStateMonitor extends Handler {
            case EVENT_CHARGING_STATE_CHANGED:
            case EVENT_TETHERING_STATE_CHANGED:
            case EVENT_UPDATE_ALWAYS_REPORT_SIGNAL_STRENGTH:
            case EVENT_CAR_MODE_CHANGED:
            case EVENT_AUTOMOTIVE_PROJECTION_STATE_CHANGED:
                onUpdateDeviceState(msg.what, msg.arg1 != 0);
                break;
            case EVENT_WIFI_CONNECTION_CHANGED:
@@ -504,9 +504,9 @@ public class DeviceStateMonitor extends Handler {
                if (mIsAlwaysSignalStrengthReportingEnabled == state) return;
                mIsAlwaysSignalStrengthReportingEnabled = state;
                break;
            case EVENT_CAR_MODE_CHANGED:
                if (mIsCarModeOn == state) return;
                mIsCarModeOn = state;
            case EVENT_AUTOMOTIVE_PROJECTION_STATE_CHANGED:
                if (mIsAutomotiveProjectionActive == state) return;
                mIsAutomotiveProjectionActive = state;
                break;
            default:
                return;
@@ -727,15 +727,16 @@ public class DeviceStateMonitor extends Handler {
    }

    /**
     * @return True if car mode (Android Auto) is on.
     * @return True if automotive projection (Android Auto) is active.
     */
    private boolean isCarModeOn() {
    private boolean isAutomotiveProjectionActive() {
        final UiModeManager umm = (UiModeManager) mPhone.getContext().getSystemService(
                Context.UI_MODE_SERVICE);
        if (umm == null) return false;
        boolean retval = umm.getCurrentModeType() == Configuration.UI_MODE_TYPE_CAR;
        log("isCarModeOn=" + retval, true);
        return retval;
        boolean isAutomotiveProjectionActive = (umm.getActiveProjectionTypes()
                & PROJECTION_TYPE_AUTOMOTIVE) != 0;
        log("isAutomotiveProjectionActive=" + isAutomotiveProjectionActive, true);
        return isAutomotiveProjectionActive;
    }

    /**
@@ -786,7 +787,7 @@ public class DeviceStateMonitor extends Handler {
        ipw.println("mIsCharging=" + mIsCharging);
        ipw.println("mIsPowerSaveOn=" + mIsPowerSaveOn);
        ipw.println("mIsLowDataExpected=" + mIsLowDataExpected);
        ipw.println("mIsCarModeOn=" + mIsCarModeOn);
        ipw.println("mIsAutomotiveProjectionActive=" + mIsAutomotiveProjectionActive);
        ipw.println("mUnsolicitedResponseFilter=" + mUnsolicitedResponseFilter);
        ipw.println("mIsWifiConnected=" + mIsWifiConnected);
        ipw.println("mIsAlwaysSignalStrengthReportingEnabled="
+4 −1
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@ import android.app.AlarmManager;
import android.app.AppOpsManager;
import android.app.DownloadManager;
import android.app.NotificationManager;
import android.app.UiModeManager;
import android.app.usage.UsageStatsManager;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
@@ -299,6 +300,8 @@ public class ContextFixture implements TestFixture<Context> {
                return Context.CARRIER_CONFIG_SERVICE;
            } else if (serviceClass == TelephonyManager.class) {
                return Context.TELEPHONY_SERVICE;
            } else if (serviceClass == UiModeManager.class) {
                return Context.UI_MODE_SERVICE;
            }
            return super.getSystemServiceName(serviceClass);
        }
+9 −0
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ import static org.mockito.Matchers.anyBoolean;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.eq;
import static org.mockito.Matchers.nullable;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.verify;
@@ -32,6 +33,8 @@ import static org.mockito.Mockito.verify;
import static java.util.Arrays.asList;

import android.annotation.IntDef;
import android.app.UiModeManager;
import android.content.Context;
import android.content.Intent;
import android.hardware.radio.V1_5.IndicationFilter;
import android.net.ConnectivityManager;
@@ -46,6 +49,7 @@ import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -127,6 +131,8 @@ public class DeviceStateMonitorTest extends TelephonyTest {
                STATE_TYPE_CHARGING, STATE_TYPE_SCREEN, STATE_TYPE_TETHERING}
    );

    @Mock
    UiModeManager mUiModeManager;
    private DeviceStateMonitor mDSM;
    // Given a stateType, return the event type that can change the state
    private int state2Event(@StateType int stateType) {
@@ -154,6 +160,9 @@ public class DeviceStateMonitorTest extends TelephonyTest {
    @Before
    public void setUp() throws Exception {
        super.setUp(getClass().getSimpleName());
        mContextFixture.setSystemService(Context.UI_MODE_SERVICE, mUiModeManager);
        // We don't even need a mock executor, we just need to not throw.
        doReturn(null).when(mContextFixture.getTestDouble()).getMainExecutor();
        mDSM = new DeviceStateMonitor(mPhone);

        // Initialize with ALL states off