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

Commit 4673b439 authored by Tyler Gunn's avatar Tyler Gunn Committed by Android (Google) Code Review
Browse files

Merge "Add RoleManagerAdapter to abstract out Telecom usage of RoleManager:"

parents e057baf4 7fd7a884
Loading
Loading
Loading
Loading
+17 −1
Original line number Diff line number Diff line
@@ -287,6 +287,7 @@ public class CallsManager extends Call.ListenerBase
    /* Handler tied to thread in which CallManager was initialized. */
    private final Handler mHandler = new Handler(Looper.getMainLooper());
    private final EmergencyCallHelper mEmergencyCallHelper;
    private final RoleManagerAdapter mRoleManagerAdapter;

    private final ConnectionServiceFocusManager.CallsManagerRequester mRequester =
            new ConnectionServiceFocusManager.CallsManagerRequester() {
@@ -392,7 +393,8 @@ public class CallsManager extends Call.ListenerBase
            BluetoothStateReceiver bluetoothStateReceiver,
            CallAudioRouteStateMachine.Factory callAudioRouteStateMachineFactory,
            CallAudioModeStateMachine.Factory callAudioModeStateMachineFactory,
            InCallControllerFactory inCallControllerFactory) {
            InCallControllerFactory inCallControllerFactory,
            RoleManagerAdapter roleManagerAdapter) {
        mContext = context;
        mLock = lock;
        mPhoneNumberUtilsAdapter = phoneNumberUtilsAdapter;
@@ -466,6 +468,7 @@ public class CallsManager extends Call.ListenerBase
                new ConnectionServiceRepository(mPhoneAccountRegistrar, mContext, mLock, this);
        mInCallWakeLockController = inCallWakeLockControllerFactory.create(context, this);
        mClockProxy = clockProxy;
        mRoleManagerAdapter = roleManagerAdapter;

        mListeners.add(mInCallWakeLockController);
        mListeners.add(statusBarNotifier);
@@ -515,6 +518,10 @@ public class CallsManager extends Call.ListenerBase
        return mCallerInfoLookupHelper;
    }

    public RoleManagerAdapter getRoleManagerAdapter() {
        return mRoleManagerAdapter;
    }

    @Override
    public void onSuccessfulOutgoingCall(Call call, int callState) {
        Log.v(this, "onSuccessfulOutgoingCall, %s", call);
@@ -3197,6 +3204,7 @@ public class CallsManager extends Call.ListenerBase
    public void onUserSwitch(UserHandle userHandle) {
        mCurrentUserHandle = userHandle;
        mMissedCallNotifier.setCurrentUserHandle(userHandle);
        mRoleManagerAdapter.setCurrentUserHandle(userHandle);
        final UserManager userManager = UserManager.get(mContext);
        List<UserInfo> profiles = userManager.getEnabledProfiles(userHandle.getIdentifier());
        for (UserInfo profile : profiles) {
@@ -3471,6 +3479,14 @@ public class CallsManager extends Call.ListenerBase
            mConnectionServiceRepository.dump(pw);
            pw.decreaseIndent();
        }

        if (mRoleManagerAdapter != null && mRoleManagerAdapter instanceof RoleManagerAdapterImpl) {
            RoleManagerAdapterImpl impl = (RoleManagerAdapterImpl) mRoleManagerAdapter;
            pw.println("mRoleManager:");
            pw.increaseIndent();
            impl.dump(pw);
            pw.decreaseIndent();
        }
    }

    /**
+82 −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.server.telecom;

import android.os.UserHandle;

import java.util.List;

/**
 * Provides a means of wrapping {@code RoleManager} operations which Telecom uses to aid in testing
 * and remove direct dependencies.
 */
public interface RoleManagerAdapter {
    /**
     * Returns the package name of the app which fills the {@link android.app.role.RoleManager} call
     * screening role.
     * @return the package name of the app filling the role, {@code null} otherwise}.
     */
    String getDefaultCallScreeningApp();

    /**
     * Override the {@link android.app.role.RoleManager} call screening app with another value.
     * Used for testing purposes only.
     * @param packageName Package name of the app to fill the call screening role.  Where
     *                    {@code null}, the override is removed.
     */
    void setTestDefaultCallScreeningApp(String packageName);

    /**
     * Retrieves a list of package names of the app(s) which fill the
     * {@link android.app.role.RoleManager} companion device role.
     * @return List of package names filling the role, or empty list if there are none.
     */
    List<String> getCallCompanionApps();

    /**
     * Set a package to be added to the list of the {@link android.app.role.RoleManager} companion
     * apps.  Used for testing purposes only.
     * @param packageName Package name of the app to be added or removed as an override call
     *                    companion app.
     * @param isAdded {@code true} if the specified package should be added, {@code false} if it
     *                            should be removed.
     */
    void addOrRemoveTestCallCompanionApp(String packageName, boolean isAdded);

    /**
     * Returns the package name of the app which fills the {@link android.app.role.RoleManager}
     * projection mode role.
     * @return Package name of the car more app or {@code null} if there are no apps that fill this
     * role.
     */
    String getCarModeDialerApp();

    /**
     * Override the {@link android.app.role.RoleManager} automotive app with another value.
     * Used for testing purposes only.
     * @param packageName Package name of the app to fill the automotive app role.  Where
     *                    {@code null}, the override is removed.
     */
    void setTestAutoModeApp(String packageName);

    /**
     * Using role manager needs to know the current user handle.  Need to make sure the role manager
     * adapter can pass this to role manager.  As it changes, we'll pass it in.
     * @param currentUserHandle The new user handle.
     */
    void setCurrentUserHandle(UserHandle currentUserHandle);
}
+152 −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.server.telecom;

import android.app.role.RoleManager;
import android.os.UserHandle;

import com.android.internal.util.IndentingPrintWriter;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

public class RoleManagerAdapterImpl implements RoleManagerAdapter {
    // TODO: replace with actual role manager const.
    private static final String ROLE_CAR_MODE_DIALER = "android.app.role.ROLE_CAR_MODE_DIALER";
    // TODO: replace with actual role manager const.
    private static final String ROLE_CALL_SCREENING = "android.app.role.CALL_SCREENING";
    // TODO: replace with actual role manager const.
    private static final String ROLE_CALL_COMPANION_APP =
            "android.app.role.ROLE_CALL_COMPANION_APP";

    private String mOverrideDefaultCallScreeningApp = null;
    private String mOverrideDefaultCarModeApp = null;
    private List<String> mOverrideCallCompanionApps = new ArrayList<>();
    private RoleManager mRoleManager;
    private UserHandle mCurrentUserHandle;

    public RoleManagerAdapterImpl(RoleManager roleManager) {
        mRoleManager = roleManager;
    }

    @Override
    public String getDefaultCallScreeningApp() {
        if (mOverrideDefaultCallScreeningApp != null) {
            return mOverrideDefaultCallScreeningApp;
        }
        return getRoleManagerCallScreeningApp();
    }

    @Override
    public void setTestDefaultCallScreeningApp(String packageName) {
        mOverrideDefaultCallScreeningApp = packageName;
    }

    @Override
    public List<String> getCallCompanionApps() {
        List<String> callCompanionApps = getRoleManagerCallCompanionApps();
        callCompanionApps.addAll(mOverrideCallCompanionApps);
        return callCompanionApps;
    }

    @Override
    public void addOrRemoveTestCallCompanionApp(String packageName, boolean isAdded) {
        if (isAdded) {
            mOverrideCallCompanionApps.add(packageName);
        } else {
            mOverrideCallCompanionApps.remove(packageName);
        }
    }

    @Override
    public String getCarModeDialerApp() {
        if (mOverrideDefaultCarModeApp != null) {
            return mOverrideDefaultCarModeApp;
        }
        return getRoleManagerCarModeDialerApp();
    }

    @Override
    public void setTestAutoModeApp(String packageName) {
        mOverrideDefaultCarModeApp = packageName;
    }

    @Override
    public void setCurrentUserHandle(UserHandle currentUserHandle) {
        mCurrentUserHandle = currentUserHandle;
    }

    private String getRoleManagerCallScreeningApp() {
        List<String> roleHolders = mRoleManager.getRoleHoldersAsUser(ROLE_CALL_SCREENING,
                mCurrentUserHandle);
        if (roleHolders == null || roleHolders.isEmpty()) {
            return null;
        }
        return roleHolders.get(0);
    }

    private String getRoleManagerCarModeDialerApp() {
        List<String> roleHolders = mRoleManager.getRoleHoldersAsUser(ROLE_CAR_MODE_DIALER,
                mCurrentUserHandle);
        if (roleHolders == null || roleHolders.isEmpty()) {
            return null;
        }
        return roleHolders.get(0);
    }

    private List<String> getRoleManagerCallCompanionApps() {
        return mRoleManager.getRoleHoldersAsUser(ROLE_CALL_COMPANION_APP, mCurrentUserHandle);
    }

    /**
     * Dumps the state of the {@link InCallController}.
     *
     * @param pw The {@code IndentingPrintWriter} to write the state to.
     */
    public void dump(IndentingPrintWriter pw) {
        pw.print("DefaultCallScreeningApp: ");
        if (mOverrideDefaultCallScreeningApp != null) {
            pw.print("(override ");
            pw.print(mOverrideDefaultCallScreeningApp);
            pw.print(") ");
            pw.print(getRoleManagerCallScreeningApp());
        }
        pw.println();

        pw.print("DefaultCarModeDialerApp: ");
        if (mOverrideDefaultCallScreeningApp != null) {
            pw.print("(override ");
            pw.print(mOverrideDefaultCarModeApp);
            pw.print(") ");
            pw.print(getRoleManagerCarModeDialerApp());
        }
        pw.println();

        pw.print("DefaultCallCompanionApps: ");
        if (mOverrideDefaultCallScreeningApp != null) {
            pw.print("(override ");
            pw.print(mOverrideCallCompanionApps.stream().collect(Collectors.joining(", ")));
            pw.print(") ");
            List<String> appsInRole = getRoleManagerCallCompanionApps();
            if (appsInRole != null) {
                pw.print(appsInRole.stream().collect(Collectors.joining(", ")));
            }
        }
        pw.println();
    }
}
+66 −0
Original line number Diff line number Diff line
@@ -39,6 +39,7 @@ import android.content.pm.ServiceInfo;
import android.content.res.Resources;
import android.net.Uri;
import android.os.Binder;
import android.os.Build;
import android.os.Bundle;
import android.os.Process;
import android.os.UserHandle;
@@ -1666,6 +1667,71 @@ public class TelecomServiceImpl {
                Log.endSession();
            }
        }

        @Override
        public void setTestDefaultCallScreeningApp(String packageName) {
            try {
                Log.startSession("TSI.sTDCSA");
                enforceModifyPermission();
                if (!Build.IS_USERDEBUG) {
                    throw new SecurityException("Test-only API.");
                }
                synchronized (mLock) {
                    long token = Binder.clearCallingIdentity();
                    try {
                        mCallsManager.getRoleManagerAdapter().setTestDefaultCallScreeningApp(
                                packageName);
                    } finally {
                        Binder.restoreCallingIdentity(token);
                    }
                }
            } finally {
                Log.endSession();
            }
        }

        @Override
        public void addOrRemoveTestCallCompanionApp(String packageName, boolean isAdded) {
            try {
                Log.startSession("TSI.aORTCCA");
                enforceModifyPermission();
                if (!Build.IS_USERDEBUG) {
                    throw new SecurityException("Test-only API.");
                }
                synchronized (mLock) {
                    long token = Binder.clearCallingIdentity();
                    try {
                        mCallsManager.getRoleManagerAdapter().addOrRemoveTestCallCompanionApp(
                                packageName, isAdded);
                    } finally {
                        Binder.restoreCallingIdentity(token);
                    }
                }
            } finally {
                Log.endSession();
            }
        }

        @Override
        public void setTestAutoModeApp(String packageName) {
            try {
                Log.startSession("TSI.sTAMA");
                enforceModifyPermission();
                if (!Build.IS_USERDEBUG) {
                    throw new SecurityException("Test-only API.");
                }
                synchronized (mLock) {
                    long token = Binder.clearCallingIdentity();
                    try {
                        mCallsManager.getRoleManagerAdapter().setTestAutoModeApp(packageName);
                    } finally {
                        Binder.restoreCallingIdentity(token);
                    }
                }
            } finally {
                Log.endSession();
            }
        }
    };

    /**
+6 −1
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ import com.android.server.telecom.CallAudioManager.AudioServiceFactory;
import com.android.server.telecom.DefaultDialerCache.DefaultDialerManagerAdapter;

import android.Manifest;
import android.app.role.RoleManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -257,6 +258,9 @@ public class TelecomSystem {
            }
        };

        RoleManagerAdapter roleManagerAdapter = new RoleManagerAdapterImpl(
                (RoleManager) mContext.getSystemService(Context.ROLE_SERVICE));

        mCallsManager = new CallsManager(
                mContext,
                mLock,
@@ -282,7 +286,8 @@ public class TelecomSystem {
                bluetoothStateReceiver,
                callAudioRouteStateMachineFactory,
                new CallAudioModeStateMachine.Factory(),
                inCallControllerFactory);
                inCallControllerFactory,
                roleManagerAdapter);

        mIncomingCallNotifier = incomingCallNotifier;
        incomingCallNotifier.setCallsManagerProxy(new IncomingCallNotifier.CallsManagerProxy() {
Loading