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

Commit 8755e29f authored by Hall Liu's avatar Hall Liu
Browse files

Refactor and fix MissedCallNotifier

This change affects the behavior of the MissedCallNotifier on system
startup. Previously, MissedCallNotifierImpl created a new Call object
and used it to pull in contacts-related data. This created excessive
dependencies for MissedCallNotifierImpl, so it has been changed to use
CallerInfoLookupHelper.

Additionally, the at-boot notification has been broken for some time,
and this was due to the calls/contacts db not being ready when
TelecomSystem was initialized. This change also deferrs the missed call
lookup to when we receive ACTION_BOOT_COMPLETE.

Test: Added unit tests, tested manually on device
Change-Id: I10fe1c78e24484ece6b87fa986e725b00c753d39
Merged-In: Ibf8ec41d8d18b5ed7943a9520242f15bf546bda7
Fix: 30796667
parent afbe4e88
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -166,7 +166,8 @@ public final class CallLogManager extends CallsManagerListenerBase {
                    new LogCallCompletedListener() {
                        @Override
                        public void onLogCompleted(@Nullable Uri uri) {
                            mMissedCallNotifier.showMissedCallNotification(call);
                            mMissedCallNotifier.showMissedCallNotification(
                                    new MissedCallNotifier.CallInfo(call));
                        }
                    });
        } else {
+9 −3
Original line number Diff line number Diff line
@@ -391,7 +391,8 @@ public class CallsManager extends Call.ListenerBase
                        result.shouldShowNotification);
            } else if (result.shouldShowNotification) {
                Log.i(this, "onCallScreeningCompleted: blocked call, showing notification.");
                mMissedCallNotifier.showMissedCallNotification(incomingCall);
                mMissedCallNotifier.showMissedCallNotification(
                        new MissedCallNotifier.CallInfo(incomingCall));
            }
        }
    }
@@ -2016,8 +2017,13 @@ public class CallsManager extends Call.ListenerBase
    }

    private void reloadMissedCallsOfUser(UserHandle userHandle) {
        mMissedCallNotifier.reloadFromDatabase(
                mLock, this, mContactsAsyncHelper, mCallerInfoAsyncQueryFactory, userHandle);
        mMissedCallNotifier.reloadFromDatabase(mCallerInfoLookupHelper,
                new MissedCallNotifier.CallInfoFactory(), userHandle);
    }

    public void onBootCompleted() {
        mMissedCallNotifier.reloadAfterBootComplete(mCallerInfoLookupHelper,
                new MissedCallNotifier.CallInfoFactory());
    }

    /**
+66 −7
Original line number Diff line number Diff line
@@ -16,23 +16,82 @@

package com.android.server.telecom;

import android.net.Uri;
import android.os.UserHandle;
import android.telecom.PhoneAccountHandle;

import com.android.internal.telephony.CallerInfo;

/**
 * Creates a notification for calls that the user missed (neither answered nor rejected).
 */
public interface MissedCallNotifier extends CallsManager.CallsManagerListener {
    class CallInfoFactory {
        public CallInfo makeCallInfo(CallerInfo callerInfo, PhoneAccountHandle phoneAccountHandle,
                Uri handle, long creationTimeMillis) {
            return new CallInfo(callerInfo, phoneAccountHandle, handle, creationTimeMillis);
        }
    }

    class CallInfo {
        private CallerInfo mCallerInfo;
        private PhoneAccountHandle mPhoneAccountHandle;
        private Uri mHandle;
        private long mCreationTimeMillis;

        public CallInfo(CallerInfo callerInfo, PhoneAccountHandle phoneAccountHandle, Uri handle,
                long creationTimeMillis) {
            mCallerInfo = callerInfo;
            mPhoneAccountHandle = phoneAccountHandle;
            mHandle = handle;
            mCreationTimeMillis = creationTimeMillis;
        }

        public CallInfo(Call call) {
            mCallerInfo = call.getCallerInfo();
            mPhoneAccountHandle = call.getTargetPhoneAccount();
            mHandle = call.getHandle();
            mCreationTimeMillis = call.getCreationTimeMillis();
        }

        public CallerInfo getCallerInfo() {
            return mCallerInfo;
        }

        public PhoneAccountHandle getPhoneAccountHandle() {
            return mPhoneAccountHandle;
        }

        public Uri getHandle() {
            return mHandle;
        }

        public String getHandleSchemeSpecificPart() {
            return mHandle == null ? null : mHandle.getSchemeSpecificPart();
        }

        public long getCreationTimeMillis() {
            return mCreationTimeMillis;
        }

        public String getPhoneNumber() {
            return mCallerInfo == null ? null : mCallerInfo.phoneNumber;
        }

        public String getName() {
            return mCallerInfo == null ? null : mCallerInfo.name;
        }
    }

    void clearMissedCalls(UserHandle userHandle);

    void showMissedCallNotification(Call call);
    void showMissedCallNotification(CallInfo call);

    void reloadAfterBootComplete(CallerInfoLookupHelper callerInfoLookupHelper,
            CallInfoFactory callInfoFactory);

    void reloadFromDatabase(
            TelecomSystem.SyncRoot lock,
            CallsManager callsManager,
            ContactsAsyncHelper contactsAsyncHelper,
            CallerInfoAsyncQueryFactory callerInfoAsyncQueryFactory,
            UserHandle userHandle);
    void reloadFromDatabase(CallerInfoLookupHelper callerInfoLookupHelper,
            CallInfoFactory callInfoFactory, UserHandle userHandle);

    void setCurrentUserHandle(UserHandle userHandle);
}
+38 −9
Original line number Diff line number Diff line
@@ -38,7 +38,7 @@ import java.io.InputStream;
/**
 * Top-level Application class for Telecom.
 */
public final class TelecomSystem {
public class TelecomSystem {

    /**
     * This interface is implemented by system-instantiated components (e.g., Services and
@@ -68,6 +68,9 @@ public final class TelecomSystem {
    private static final IntentFilter USER_STARTING_FILTER =
            new IntentFilter(Intent.ACTION_USER_STARTING);

    private static final IntentFilter BOOT_COMPLETE_FILTER =
            new IntentFilter(Intent.ACTION_BOOT_COMPLETED);

    /** Intent filter for dialer secret codes. */
    private static final IntentFilter DIALER_SECRET_CODE_FILTER;

@@ -102,15 +105,19 @@ public final class TelecomSystem {
    private final ContactsAsyncHelper mContactsAsyncHelper;
    private final DialerCodeReceiver mDialerCodeReceiver;

    private boolean mIsBootComplete = false;

    private final BroadcastReceiver mUserSwitchedReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            Log.startSession("TSSwR.oR");
            try {
                synchronized (mLock) {
                    int userHandleId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
                    UserHandle currentUserHandle = new UserHandle(userHandleId);
                    mPhoneAccountRegistrar.setCurrentUserHandle(currentUserHandle);
                    mCallsManager.onUserSwitch(currentUserHandle);
                }
            } finally {
                Log.endSession();
            }
@@ -122,9 +129,26 @@ public final class TelecomSystem {
        public void onReceive(Context context, Intent intent) {
            Log.startSession("TSStR.oR");
            try {
                synchronized (mLock) {
                    int userHandleId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
                    UserHandle addingUserHandle = new UserHandle(userHandleId);
                    mCallsManager.onUserStarting(addingUserHandle);
                }
            } finally {
                Log.endSession();
            }
        }
    };

    private final BroadcastReceiver mBootCompletedReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            Log.startSession("TSBCR.oR");
            try {
                synchronized (mLock) {
                    mIsBootComplete = true;
                    mCallsManager.onBootCompleted();
                }
            } finally {
                Log.endSession();
            }
@@ -137,7 +161,7 @@ public final class TelecomSystem {

    public static void setInstance(TelecomSystem instance) {
        if (INSTANCE != null) {
            throw new RuntimeException("Attempt to set TelecomSystem.INSTANCE twice");
            Log.w("TelecomSystem", "Attempt to set TelecomSystem.INSTANCE twice");
        }
        Log.i(TelecomSystem.class, "TelecomSystem.INSTANCE being set");
        INSTANCE = instance;
@@ -203,6 +227,7 @@ public final class TelecomSystem {

        mContext.registerReceiver(mUserSwitchedReceiver, USER_SWITCHED_FILTER);
        mContext.registerReceiver(mUserStartingReceiver, USER_STARTING_FILTER);
        mContext.registerReceiver(mBootCompletedReceiver, BOOT_COMPLETE_FILTER);

        mBluetoothPhoneServiceImpl = bluetoothPhoneServiceImplFactory.makeBluetoothPhoneServiceImpl(
                mContext, mLock, mCallsManager, mPhoneAccountRegistrar);
@@ -259,4 +284,8 @@ public final class TelecomSystem {
    public Object getLock() {
        return mLock;
    }

    public boolean isBootComplete() {
        return mIsBootComplete;
    }
}
Loading