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

Commit 6a8fbb9d authored by Tyler Gunn's avatar Tyler Gunn
Browse files

Handle prioritized car mode in Telecom.

Add basic support for receiving the broadcast that the prioritized car
mode has changed in Telecom; rest of implementation TBD.
Also added a fancy new car mode dialer app which can be used in car mode.

Bug: 136109592
Test: Use new test app to verify enter/exit car mode with priority.
Test: Run new CTS tests.
Change-Id: I93daadf341e7c158260a1cc76efc6085a29f7a38
parent 42d96a38
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@
    <uses-permission android:name="android.permission.BROADCAST_PHONE_ACCOUNT_REGISTRATION" />
    <uses-permission android:name="android.permission.CALL_PRIVILEGED" />
    <uses-permission android:name="android.permission.HANDLE_CALL_INTENT" />
    <uses-permission android:name="android.permission.HANDLE_CAR_MODE_CHANGES" />
    <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS" />
    <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" />
    <uses-permission android:name="android.permission.MANAGE_USERS" />
+4 −0
Original line number Diff line number Diff line
@@ -707,6 +707,10 @@ public class InCallController extends CallsManagerListenerBase {
                mInCallServiceConnection.setCarMode(shouldUseCarModeUI());
            }
        }

        @Override
        public void onCarModeChanged(int priority, String packageName, boolean isCarMode) {
        }
    };

    private static final int IN_CALL_SERVICE_TYPE_INVALID = 0;
+45 −1
Original line number Diff line number Diff line
@@ -39,7 +39,17 @@ import java.util.concurrent.atomic.AtomicBoolean;
 */
public class SystemStateHelper {
    public static interface SystemStateListener {
        public void onCarModeChanged(boolean isCarMode);
        void onCarModeChanged(boolean isCarMode);

        /**
         * Listener method to inform interested parties when a package name requests to enter or
         * exit car mode.
         * @param priority the priority of the enter/exit request.
         * @param packageName the package name of the requester.
         * @param isCarMode {@code true} if the package is entering car mode, {@code false}
         *                              otherwise.
         */
        void onCarModeChanged(int priority, String packageName, boolean isCarMode);
    }

    private final Context mContext;
@@ -53,6 +63,22 @@ public class SystemStateHelper {
                    onEnterCarMode();
                } else if (UiModeManager.ACTION_EXIT_CAR_MODE.equals(action)) {
                    onExitCarMode();
                } else if (UiModeManager.ACTION_ENTER_CAR_MODE_PRIORITIZED.equals(action)) {
                    int priority = intent.getIntExtra(UiModeManager.EXTRA_PRIORITY,
                            UiModeManager.DEFAULT_PRIORITY);
                    String callingPackage = intent.getStringExtra(
                            UiModeManager.EXTRA_CALLING_PACKAGE);
                    Log.i(SystemStateHelper.this, "ENTER_CAR_MODE_PRIVILEGED; priority=%d, pkg=%s",
                            priority, callingPackage);
                    onEnterCarMode(priority, callingPackage);
                } else if (UiModeManager.ACTION_EXIT_CAR_MODE_PRIORITIZED.equals(action)) {
                    int priority = intent.getIntExtra(UiModeManager.EXTRA_PRIORITY,
                            UiModeManager.DEFAULT_PRIORITY);
                    String callingPackage = intent.getStringExtra(
                            UiModeManager.EXTRA_CALLING_PACKAGE);
                    Log.i(SystemStateHelper.this, "EXIT_CAR_MODE_PRIVILEGED; priority=%d, pkg=%s",
                            priority, callingPackage);
                    onExitCarMode(priority, callingPackage);
                } else {
                    Log.w(this, "Unexpected intent received: %s", intent.getAction());
                }
@@ -70,6 +96,8 @@ public class SystemStateHelper {

        IntentFilter intentFilter = new IntentFilter(UiModeManager.ACTION_ENTER_CAR_MODE);
        intentFilter.addAction(UiModeManager.ACTION_EXIT_CAR_MODE);
        intentFilter.addAction(UiModeManager.ACTION_ENTER_CAR_MODE_PRIORITIZED);
        intentFilter.addAction(UiModeManager.ACTION_EXIT_CAR_MODE_PRIORITIZED);
        mContext.registerReceiver(mBroadcastReceiver, intentFilter);
        Log.i(this, "Registering car mode receiver: %s", intentFilter);

@@ -186,6 +214,22 @@ public class SystemStateHelper {
        }
    }

    private void onEnterCarMode(int priority, String packageName) {
       Log.i(this, "Entering carmode");
       mIsCarMode = getSystemCarMode();
        for (SystemStateListener listener : mListeners) {
            listener.onCarModeChanged(priority, packageName, true /* isCarMode */);
        }
    }

    private void onExitCarMode(int priority, String packageName) {
        Log.i(this, "Exiting carmode");
        mIsCarMode = getSystemCarMode();
        for (SystemStateListener listener : mListeners) {
            listener.onCarModeChanged(priority, packageName, false /* isCarMode */);
        }
    }

    private void notifyCarMode() {
        for (SystemStateListener listener : mListeners) {
            listener.onCarModeChanged(mIsCarMode);
+26 −0
Original line number Diff line number Diff line
//
// 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.
//

android_test {
    name: "TelecomCarModeApp",
    static_libs: [
        "androidx.legacy_legacy-support-v4",
        "guava",
    ],
    srcs: ["src/**/*.java"],
    platform_apis: true,
    certificate: "platform",
}
+90 −0
Original line number Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?>
<!-- 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.
-->

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          coreApp="true"
          package="com.android.server.telecom.carmodedialer">

    <uses-sdk
        android:minSdkVersion="28"
        android:targetSdkVersion="29" />

    <uses-permission android:name="android.permission.ACCEPT_HANDOVER" />
    <uses-permission android:name="android.permission.BLUETOOTH" />
    <uses-permission android:name="android.permission.CALL_PHONE" />
    <uses-permission android:name="android.permission.CONTROL_INCALL_EXPERIENCE" />
    <uses-permission android:name="android.permission.ENTER_CAR_MODE_PRIORITIZED" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.READ_CALL_LOG" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.WRITE_CALL_LOG" />

    <application android:label="Telecom CarMode">
        <uses-library android:name="android.test.runner" />

        <service android:name="com.android.server.telecom.carmodedialer.CarModeInCallServiceImpl"
                 android:permission="android.permission.BIND_INCALL_SERVICE" >
          <meta-data android:name="android.telecom.IN_CALL_SERVICE_CAR_MODE_UI"
                     android:value="true"/>
          <intent-filter>
              <action android:name="android.telecom.InCallService"/>
          </intent-filter>
        </service>

        <activity android:name="com.android.server.telecom.carmodedialer.CarModeInCallUI"
                android:label="CarMode Dialer"
                android:launchMode="singleInstance">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <activity android:name="com.android.server.telecom.carmodedialer.CarModeDialerActivity"
                  android:label="CarMode Dialer">
            <intent-filter>
                <action android:name="android.intent.action.DIAL" />
                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />
                <data android:mimeType="vnd.android.cursor.item/phone" />
                <data android:mimeType="vnd.android.cursor.item/person" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.intent.action.DIAL" />
                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />
                <data android:scheme="voicemail" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.intent.action.DIAL" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.intent.action.VIEW" />
                <action android:name="android.intent.action.DIAL" />
                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />
                <data android:scheme="tel" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>
Loading