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

Commit 287caa98 authored by Treehugger Robot's avatar Treehugger Robot Committed by Automerger Merge Worker
Browse files

Merge "Revert "Improve CallsLogManager logging code."" into udc-d1-dev am: c33b98fd

parents 62d84956 c33b98fd
Loading
Loading
Loading
Loading
+61 −126
Original line number Original line Diff line number Diff line
@@ -19,20 +19,17 @@ package com.android.server.telecom;
import static android.provider.CallLog.Calls.BLOCK_REASON_NOT_BLOCKED;
import static android.provider.CallLog.Calls.BLOCK_REASON_NOT_BLOCKED;
import static android.telephony.CarrierConfigManager.KEY_SUPPORT_IMS_CONFERENCE_EVENT_PACKAGE_BOOL;
import static android.telephony.CarrierConfigManager.KEY_SUPPORT_IMS_CONFERENCE_EVENT_PACKAGE_BOOL;


import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.Nullable;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Context;
import android.content.Intent;
import android.content.Intent;
import android.database.Cursor;
import android.location.Country;
import android.location.Country;
import android.location.CountryDetector;
import android.location.CountryDetector;
import android.location.Location;
import android.location.Location;
import android.net.Uri;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Looper;
import android.os.Looper;
import android.os.UserHandle;
import android.os.UserHandle;
import android.os.PersistableBundle;
import android.os.PersistableBundle;
import android.os.UserManager;
import android.provider.CallLog;
import android.provider.CallLog;
import android.provider.CallLog.Calls;
import android.provider.CallLog.Calls;
import android.telecom.Connection;
import android.telecom.Connection;
@@ -45,7 +42,6 @@ import android.telecom.VideoProfile;
import android.telephony.CarrierConfigManager;
import android.telephony.CarrierConfigManager;
import android.telephony.PhoneNumberUtils;
import android.telephony.PhoneNumberUtils;
import android.telephony.SubscriptionManager;
import android.telephony.SubscriptionManager;
import android.util.Pair;


import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.annotations.VisibleForTesting;
import com.android.server.telecom.callfiltering.CallFilteringResult;
import com.android.server.telecom.callfiltering.CallFilteringResult;
@@ -53,8 +49,6 @@ import com.android.server.telecom.callfiltering.CallFilteringResult;
import java.util.Arrays;
import java.util.Arrays;
import java.util.Locale;
import java.util.Locale;
import java.util.Objects;
import java.util.Objects;
import java.util.UUID;
import java.util.concurrent.Executor;
import java.util.stream.Stream;
import java.util.stream.Stream;


/**
/**
@@ -74,19 +68,16 @@ public final class CallLogManager extends CallsManagerListenerBase {
     */
     */
    private static class AddCallArgs {
    private static class AddCallArgs {
        public AddCallArgs(Context context, CallLog.AddCallParams params,
        public AddCallArgs(Context context, CallLog.AddCallParams params,
                @Nullable LogCallCompletedListener logCallCompletedListener,
                @Nullable LogCallCompletedListener logCallCompletedListener) {
                @NonNull String callId) {
            this.context = context;
            this.context = context;
            this.params = params;
            this.params = params;
            this.logCallCompletedListener = logCallCompletedListener;
            this.logCallCompletedListener = logCallCompletedListener;
            this.callId = callId;


        }
        }
        // Since the members are accessed directly, we don't use the
        // Since the members are accessed directly, we don't use the
        // mXxxx notation.
        // mXxxx notation.
        public final Context context;
        public final Context context;
        public final CallLog.AddCallParams params;
        public final CallLog.AddCallParams params;
        public final String callId;
        @Nullable
        @Nullable
        public final LogCallCompletedListener logCallCompletedListener;
        public final LogCallCompletedListener logCallCompletedListener;
    }
    }
@@ -97,17 +88,11 @@ public final class CallLogManager extends CallsManagerListenerBase {
    // TODO: come up with a better way to indicate in a android.telecom.DisconnectCause that
    // TODO: come up with a better way to indicate in a android.telecom.DisconnectCause that
    // a conference was merged successfully
    // a conference was merged successfully
    private static final String REASON_IMS_MERGED_SUCCESSFULLY = "IMS_MERGED_SUCCESSFULLY";
    private static final String REASON_IMS_MERGED_SUCCESSFULLY = "IMS_MERGED_SUCCESSFULLY";
    private static final UUID LOG_CALL_FAILED_ANOMALY_ID =
            UUID.fromString("1c4c15f3-ab4f-459c-b9ef-43d2988bae82");
    private static final String LOG_CALL_FAileD_ANOMALY_DESC =
            "Failed to record a call to the call log.";


    private final Context mContext;
    private final Context mContext;
    private final CarrierConfigManager mCarrierConfigManager;
    private final CarrierConfigManager mCarrierConfigManager;
    private final PhoneAccountRegistrar mPhoneAccountRegistrar;
    private final PhoneAccountRegistrar mPhoneAccountRegistrar;
    private final MissedCallNotifier mMissedCallNotifier;
    private final MissedCallNotifier mMissedCallNotifier;
    private final Executor mCallLogExecutor;
    private AnomalyReporterAdapter mAnomalyReporterAdapter;
    private static final String ACTION_CALLS_TABLE_ADD_ENTRY =
    private static final String ACTION_CALLS_TABLE_ADD_ENTRY =
                "com.android.server.telecom.intent.action.CALLS_ADD_ENTRY";
                "com.android.server.telecom.intent.action.CALLS_ADD_ENTRY";
    private static final String PERMISSION_PROCESS_CALLLOG_INFO =
    private static final String PERMISSION_PROCESS_CALLLOG_INFO =
@@ -119,15 +104,12 @@ public final class CallLogManager extends CallsManagerListenerBase {
    private String mCurrentCountryIso;
    private String mCurrentCountryIso;


    public CallLogManager(Context context, PhoneAccountRegistrar phoneAccountRegistrar,
    public CallLogManager(Context context, PhoneAccountRegistrar phoneAccountRegistrar,
            MissedCallNotifier missedCallNotifier, AnomalyReporterAdapter anomalyReporterAdapter,
            MissedCallNotifier missedCallNotifier) {
            Executor executor) {
        mContext = context;
        mContext = context;
        mCarrierConfigManager = (CarrierConfigManager) mContext
        mCarrierConfigManager = (CarrierConfigManager) mContext
                .getSystemService(Context.CARRIER_CONFIG_SERVICE);
                .getSystemService(Context.CARRIER_CONFIG_SERVICE);
        mPhoneAccountRegistrar = phoneAccountRegistrar;
        mPhoneAccountRegistrar = phoneAccountRegistrar;
        mMissedCallNotifier = missedCallNotifier;
        mMissedCallNotifier = missedCallNotifier;
        mAnomalyReporterAdapter = anomalyReporterAdapter;
        mCallLogExecutor = executor;
        mLock = new Object();
        mLock = new Object();
    }
    }


@@ -258,10 +240,8 @@ public final class CallLogManager extends CallsManagerListenerBase {
            logCall(call, type, new LogCallCompletedListener() {
            logCall(call, type, new LogCallCompletedListener() {
                @Override
                @Override
                public void onLogCompleted(@Nullable Uri uri) {
                public void onLogCompleted(@Nullable Uri uri) {
                    mContext.getMainExecutor().execute(() -> {
                    mMissedCallNotifier.showMissedCallNotification(
                    mMissedCallNotifier.showMissedCallNotification(
                            new MissedCallNotifier.CallInfo(call));
                            new MissedCallNotifier.CallInfo(call));
                    });
                }
                }
            }, result);
            }, result);
        } else {
        } else {
@@ -405,7 +385,7 @@ public final class CallLogManager extends CallsManagerListenerBase {
                okayToLogCall(accountHandle, logNumber, call.isEmergencyCall());
                okayToLogCall(accountHandle, logNumber, call.isEmergencyCall());
        if (okayToLog) {
        if (okayToLog) {
            AddCallArgs args = new AddCallArgs(mContext, paramBuilder.build(),
            AddCallArgs args = new AddCallArgs(mContext, paramBuilder.build(),
                    logCallCompletedListener, call.getId());
                    logCallCompletedListener);
            Log.addEvent(call, LogUtils.Events.LOG_CALL, "number=" + Log.piiHandle(logNumber)
            Log.addEvent(call, LogUtils.Events.LOG_CALL, "number=" + Log.piiHandle(logNumber)
                    + ",postDial=" + Log.piiHandle(call.getPostDialDigits()) + ",pres="
                    + ",postDial=" + Log.piiHandle(call.getPostDialDigits()) + ",pres="
                    + call.getHandlePresentation());
                    + call.getHandlePresentation());
@@ -511,33 +491,33 @@ public final class CallLogManager extends CallsManagerListenerBase {
     * Adds the call defined by the parameters in the provided AddCallArgs to the CallLogProvider
     * Adds the call defined by the parameters in the provided AddCallArgs to the CallLogProvider
     * using an AsyncTask to avoid blocking the main thread.
     * using an AsyncTask to avoid blocking the main thread.
     *
     *
     * @param c Prepopulated call details.
     * @param args Prepopulated call details.
     * @return A handle to the AsyncTask that will add the call to the call log asynchronously.
     */
     */
    public void logCallAsync(final AddCallArgs c) {
    public AsyncTask<AddCallArgs, Void, Uri[]> logCallAsync(AddCallArgs args) {
        mCallLogExecutor.execute(() -> {
        return new LogCallAsyncTask().execute(args);
            Uri result;
    }

    /**
     * Helper AsyncTask to access the call logs database asynchronously since database operations
     * can take a long time depending on the system's load. Since it extends AsyncTask, it uses
     * its own thread pool.
     */
    private class LogCallAsyncTask extends AsyncTask<AddCallArgs, Void, Uri[]> {

        private LogCallCompletedListener[] mListeners;

        @Override
        protected Uri[] doInBackground(AddCallArgs... callList) {
            int count = callList.length;
            Uri[] result = new Uri[count];
            mListeners = new LogCallCompletedListener[count];
            for (int i = 0; i < count; i++) {
                AddCallArgs c = callList[i];
                mListeners[i] = c.logCallCompletedListener;
                try {
                try {
                    // May block.
                    // May block.
                ContentResolver resolver = c.context.getContentResolver();
                    result[i] = Calls.addCall(c.context, c.params);
                Pair<Integer, Integer> startStats = getCallLogStats(resolver);
                Log.i(TAG, "LogCall; about to log callId=%s, "
                                + "startCount=%d, startMaxId=%d",
                        c.callId, startStats.first, startStats.second);

                result = Calls.addCall(c.context, c.params);
                Pair<Integer, Integer> endStats = getCallLogStats(resolver);
                Log.i(TAG, "LogCall; logged callId=%s, uri=%s, "
                                + "endCount=%d, endMaxId=%s",
                        c.callId, result, endStats.first, endStats.second);
                if ((endStats.second - startStats.second) <= 0) {
                    // No call was added or even worse we lost a call in the log.  Trigger an
                    // anomaly report.  Note: it technically possible that an app modified the
                    // call log while we were writing to it here; that is pretty unlikely, and
                    // the goal here is to try and identify potential anomalous conditions with
                    // logging calls.
                    mAnomalyReporterAdapter.reportAnomaly(LOG_CALL_FAILED_ANOMALY_ID,
                            LOG_CALL_FAileD_ANOMALY_DESC);
                }
                } catch (Exception e) {
                } catch (Exception e) {
                    // This is very rare but may happen in legitimate cases.
                    // This is very rare but may happen in legitimate cases.
                    // E.g. If the phone is encrypted and thus write request fails, it may cause
                    // E.g. If the phone is encrypted and thus write request fails, it may cause
@@ -546,25 +526,31 @@ public final class CallLogManager extends CallsManagerListenerBase {
                    //
                    //
                    // We don't want to crash the whole process just because of that, so just log
                    // We don't want to crash the whole process just because of that, so just log
                    // it instead.
                    // it instead.
                Log.e(TAG, e, "LogCall: Exception raised adding callId=%s", c.callId);
                    Log.e(TAG, e, "Exception raised during adding CallLog entry.");
                result = null;
                    result[i] = null;
                mAnomalyReporterAdapter.reportAnomaly(LOG_CALL_FAILED_ANOMALY_ID,
                }
                        LOG_CALL_FAileD_ANOMALY_DESC);
            }
            return result;
        }
        }


        @Override
        protected void onPostExecute(Uri[] result) {
            for (int i = 0; i < result.length; i++) {
                Uri uri = result[i];
                /*
                /*
                 Performs a simple correctness check to make sure the call was written in the
                 Performs a simple correctness check to make sure the call was written in the
                 database.
                 database.
                 Typically there is only one result per call so it is easy to identify which one
                 Typically there is only one result per call so it is easy to identify which one
                 failed.
                 failed.
                 */
                 */
            if (result == null) {
                if (uri == null) {
                Log.w(TAG, "LogCall: Failed to write call to the log.");
                    Log.w(TAG, "Failed to write call to the log.");
                }
                if (mListeners[i] != null) {
                    mListeners[i].onLogCompleted(uri);
                }
            }
            }
            if (c.logCallCompletedListener != null) {
                c.logCallCompletedListener.onLogCompleted(result);
        }
        }
        });
    }
    }


    private void sendAddCallBroadcast(int callType, long duration) {
    private void sendAddCallBroadcast(int callType, long duration) {
@@ -616,55 +602,4 @@ public final class CallLogManager extends CallsManagerListenerBase {
            return mCurrentCountryIso;
            return mCurrentCountryIso;
        }
        }
    }
    }

    /**
     * Returns a pair containing the number of rows in the call log, as well as the maximum call log
     * ID.  There is a limit of 500 entries in the call log for a phone account, so once we hit 500
     * we can reasonably expect that number to not change before and after logging a call.
     * We determine the maximum ID in the call log since this is a way we can objectively check if
     * the provider did record a call log entry or not.  Ideally there should me more call log
     * entries after logging than before, and certainly not less.
     * @param resolver content resolver
     * @return pair with number of rows in the call log and max id.
     */
    private Pair<Integer, Integer> getCallLogStats(@NonNull ContentResolver resolver) {
        try {
            final UserManager userManager = mContext.getSystemService(UserManager.class);
            final int currentUserId = userManager.getProcessUserId();

            // Use shadow provider based on current user unlock state.
            Uri providerUri;
            if (userManager.isUserUnlocked(currentUserId)) {
                providerUri = Calls.CONTENT_URI;
            } else {
                providerUri = Calls.SHADOW_CONTENT_URI;
            }
            int maxCallId = -1;
            int numFound;
            Cursor countCursor = resolver.query(providerUri,
                    new String[]{Calls._ID},
                    null,
                    null,
                    Calls._ID + " DESC");
            try {
                numFound = countCursor.getCount();
                if (numFound > 0) {
                    countCursor.moveToFirst();
                    maxCallId = countCursor.getInt(0);
                }
            } finally {
                countCursor.close();
            }
            return new Pair<>(numFound, maxCallId);
        } catch (Exception e) {
            // Oh jeepers, we crashed getting the call count.
            Log.e(TAG, e, "getCountOfCallLogRows: failed");
            return new Pair<>(-1, -1);
        }
    }

    @VisibleForTesting
    public void setAnomalyReporterAdapter(AnomalyReporterAdapter anomalyReporterAdapter){
        mAnomalyReporterAdapter = anomalyReporterAdapter;
    }
}
}
+3 −7
Original line number Original line Diff line number Diff line
@@ -655,8 +655,7 @@ public class CallsManager extends Call.ListenerBase
        mTtyManager = new TtyManager(context, mWiredHeadsetManager);
        mTtyManager = new TtyManager(context, mWiredHeadsetManager);
        mProximitySensorManager = proximitySensorManagerFactory.create(context, this);
        mProximitySensorManager = proximitySensorManagerFactory.create(context, this);
        mPhoneStateBroadcaster = new PhoneStateBroadcaster(this);
        mPhoneStateBroadcaster = new PhoneStateBroadcaster(this);
        mCallLogManager = new CallLogManager(context, phoneAccountRegistrar, mMissedCallNotifier,
        mCallLogManager = new CallLogManager(context, phoneAccountRegistrar, mMissedCallNotifier);
                mAnomalyReporter, asyncCallAudioTaskExecutor);
        mConnectionServiceRepository =
        mConnectionServiceRepository =
                new ConnectionServiceRepository(mPhoneAccountRegistrar, mContext, mLock, this);
                new ConnectionServiceRepository(mPhoneAccountRegistrar, mContext, mLock, this);
        mInCallWakeLockController = inCallWakeLockControllerFactory.create(context, this);
        mInCallWakeLockController = inCallWakeLockControllerFactory.create(context, this);
@@ -1382,11 +1381,8 @@ public class CallsManager extends Call.ListenerBase
    }
    }


    @VisibleForTesting
    @VisibleForTesting
    public void setAnomalyReporterAdapter(AnomalyReporterAdapter anomalyReporterAdapter){
    public void setAnomalyReporterAdapter(AnomalyReporterAdapter mAnomalyReporterAdapter){
        mAnomalyReporter = anomalyReporterAdapter;
        mAnomalyReporter = mAnomalyReporterAdapter;
        if (mCallLogManager != null) {
            mCallLogManager.setAnomalyReporterAdapter(anomalyReporterAdapter);
        }
    }
    }


    void processIncomingConference(PhoneAccountHandle phoneAccountHandle, Bundle extras) {
    void processIncomingConference(PhoneAccountHandle phoneAccountHandle, Bundle extras) {
+0 −6
Original line number Original line Diff line number Diff line
@@ -101,10 +101,4 @@
        android:layout_width="wrap_content"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/send_contact_discovery" />
        android:text="@string/send_contact_discovery" />

    <Button
        android:id="@+id/add_call_log_entries"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Fill Call Log" />
</LinearLayout>
</LinearLayout>
+0 −28
Original line number Original line Diff line number Diff line
@@ -6,7 +6,6 @@ import android.app.Activity;
import android.app.UiModeManager;
import android.app.UiModeManager;
import android.app.role.RoleManager;
import android.app.role.RoleManager;
import android.content.ComponentName;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.ContentValues;
import android.content.Context;
import android.content.Context;
import android.content.Intent;
import android.content.Intent;
@@ -32,7 +31,6 @@ import android.widget.Toast;


public class TestDialerActivity extends Activity {
public class TestDialerActivity extends Activity {
    private static final int REQUEST_CODE_SET_DEFAULT_DIALER = 1;
    private static final int REQUEST_CODE_SET_DEFAULT_DIALER = 1;
    private static int sEntryNumber = 1;


    private EditText mNumberView;
    private EditText mNumberView;
    private CheckBox mRttCheckbox;
    private CheckBox mRttCheckbox;
@@ -80,13 +78,6 @@ public class TestDialerActivity extends Activity {
            }
            }
        });
        });


        findViewById(R.id.add_call_log_entries).setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                addCallLogEntries();
            }
        });

        mNumberView = (EditText) findViewById(R.id.number);
        mNumberView = (EditText) findViewById(R.id.number);
        mRttCheckbox = (CheckBox) findViewById(R.id.call_with_rtt_checkbox);
        mRttCheckbox = (CheckBox) findViewById(R.id.call_with_rtt_checkbox);
        mComposerCheckbox = (CheckBox) findViewById(R.id.add_composer_attachments_checkbox);
        mComposerCheckbox = (CheckBox) findViewById(R.id.add_composer_attachments_checkbox);
@@ -246,23 +237,4 @@ public class TestDialerActivity extends Activity {
        intent.putExtra(Settings.EXTRA_SUB_ID, SubscriptionManager.getDefaultSubscriptionId());
        intent.putExtra(Settings.EXTRA_SUB_ID, SubscriptionManager.getDefaultSubscriptionId());
        startActivity(intent);
        startActivity(intent);
    }
    }

    private void addCallLogEntries() {
        ContentResolver contentResolver = getContentResolver();
        for (int ix = 0; ix < 1000; ix ++) {
            ContentValues values = new ContentValues();
            String number = String.format("1650%07d", sEntryNumber++);
            values.put(Calls.TYPE, Calls.OUTGOING_TYPE);
            values.put(Calls.NUMBER, number);
            values.put(Calls.NUMBER_PRESENTATION, Calls.PRESENTATION_ALLOWED);
            values.put(Calls.DATE, System.currentTimeMillis());
            values.put(Calls.DURATION, 10);
            values.put(Calls.PHONE_ACCOUNT_COMPONENT_NAME, "com.android.phone/com.android.services.telephony.TelephonyConnectionService");
            values.put(Calls.PHONE_ACCOUNT_ID, 1);
            values.put(Calls.PHONE_ACCOUNT_ADDRESS, "650-555-1212");
            values.put(Calls.NEW, 1);
            contentResolver.insert(Calls.CONTENT_URI, values);
        }

    }
}
}
+1 −4
Original line number Original line Diff line number Diff line
@@ -65,7 +65,6 @@ import android.test.suitebuilder.annotation.SmallTest;
import androidx.test.filters.FlakyTest;
import androidx.test.filters.FlakyTest;


import com.android.server.telecom.Analytics;
import com.android.server.telecom.Analytics;
import com.android.server.telecom.AnomalyReporterAdapter;
import com.android.server.telecom.Call;
import com.android.server.telecom.Call;
import com.android.server.telecom.CallLogManager;
import com.android.server.telecom.CallLogManager;
import com.android.server.telecom.CallState;
import com.android.server.telecom.CallState;
@@ -124,8 +123,6 @@ public class CallLogManagerTest extends TelecomTestCase {
    PhoneAccountRegistrar mMockPhoneAccountRegistrar;
    PhoneAccountRegistrar mMockPhoneAccountRegistrar;
    @Mock
    @Mock
    MissedCallNotifier mMissedCallNotifier;
    MissedCallNotifier mMissedCallNotifier;
    @Mock
    AnomalyReporterAdapter mAnomalyReporterAdapter;


    @Override
    @Override
    @Before
    @Before
@@ -133,7 +130,7 @@ public class CallLogManagerTest extends TelecomTestCase {
        super.setUp();
        super.setUp();
        mContext = mComponentContextFixture.getTestDouble().getApplicationContext();
        mContext = mComponentContextFixture.getTestDouble().getApplicationContext();
        mCallLogManager = new CallLogManager(mContext, mMockPhoneAccountRegistrar,
        mCallLogManager = new CallLogManager(mContext, mMockPhoneAccountRegistrar,
                mMissedCallNotifier, mAnomalyReporterAdapter, Runnable::run);
                mMissedCallNotifier);
        mDefaultAccountHandle = new PhoneAccountHandle(
        mDefaultAccountHandle = new PhoneAccountHandle(
                new ComponentName("com.android.server.telecom.tests", "CallLogManagerTest"),
                new ComponentName("com.android.server.telecom.tests", "CallLogManagerTest"),
                TEST_PHONE_ACCOUNT_ID,
                TEST_PHONE_ACCOUNT_ID,
Loading