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

Commit 1c5f9cfb authored by Yuri Lin's avatar Yuri Lin
Browse files

Write to Zen Log for recording callers & when checking on repeat callers

This will help us debug when calls may be recorded without phone number info, and whether subsequent attempts to check whether a call is from a repeat caller provide phone, URI, or both pieces of information.

Also log the calling UID for matchesCallFilter when it's called to track where the calls are coming from; this requires passing it through from NMS which has access to Binder.getCallingUid.

Bug: 183924362
Bug: 232941276
Test: manual verification of Zen Log from notification dumpsys; atest NMSTest, ZenModeFilteringTest
Change-Id: I73933a710acc885c6466c3b9b7ae325299ddeeb1
parent 910d0090
Loading
Loading
Loading
Loading
+2 −1
Original line number Original line Diff line number Diff line
@@ -5171,7 +5171,8 @@ public class NotificationManagerService extends SystemService {
                    extras,
                    extras,
                    mRankingHelper.findExtractor(ValidateNotificationPeople.class),
                    mRankingHelper.findExtractor(ValidateNotificationPeople.class),
                    MATCHES_CALL_FILTER_CONTACTS_TIMEOUT_MS,
                    MATCHES_CALL_FILTER_CONTACTS_TIMEOUT_MS,
                    MATCHES_CALL_FILTER_TIMEOUT_AFFINITY);
                    MATCHES_CALL_FILTER_TIMEOUT_AFFINITY,
                    Binder.getCallingUid());
        }
        }
        @Override
        @Override
+24 −3
Original line number Original line Diff line number Diff line
@@ -66,6 +66,8 @@ public class ZenLog {
    private static final int TYPE_SET_NOTIFICATION_POLICY = 16;
    private static final int TYPE_SET_NOTIFICATION_POLICY = 16;
    private static final int TYPE_SET_CONSOLIDATED_ZEN_POLICY = 17;
    private static final int TYPE_SET_CONSOLIDATED_ZEN_POLICY = 17;
    private static final int TYPE_MATCHES_CALL_FILTER = 18;
    private static final int TYPE_MATCHES_CALL_FILTER = 18;
    private static final int TYPE_RECORD_CALLER = 19;
    private static final int TYPE_CHECK_REPEAT_CALLER = 20;


    private static int sNext;
    private static int sNext;
    private static int sSize;
    private static int sSize;
@@ -167,11 +169,28 @@ public class ZenLog {
            + hintsToString(newHints) + ",listeners=" + listenerCount);
            + hintsToString(newHints) + ",listeners=" + listenerCount);
    }
    }


    /*
    /**
     * Trace calls to matchesCallFilter with the result of the call and the reason for the result.
     * Trace calls to matchesCallFilter with the result of the call and the reason for the result.
     */
     */
    public static void traceMatchesCallFilter(boolean result, String reason) {
    public static void traceMatchesCallFilter(boolean result, String reason, int callingUid) {
        append(TYPE_MATCHES_CALL_FILTER, "result=" + result + ", reason=" + reason);
        append(TYPE_MATCHES_CALL_FILTER, "result=" + result + ", reason=" + reason
                + ", calling uid=" + callingUid);
    }

    /**
     * Trace what information is available about an incoming call when it's recorded
     */
    public static void traceRecordCaller(boolean hasPhone, boolean hasUri) {
        append(TYPE_RECORD_CALLER, "has phone number=" + hasPhone + ", has uri=" + hasUri);
    }

    /**
     * Trace what information was provided about a caller when checking whether it is from a repeat
     * caller
     */
    public static void traceCheckRepeatCaller(boolean found, boolean hasPhone, boolean hasUri) {
        append(TYPE_CHECK_REPEAT_CALLER, "res=" + found + ", given phone number=" + hasPhone
                + ", given uri=" + hasUri);
    }
    }


    private static String subscribeResult(IConditionProvider provider, RemoteException e) {
    private static String subscribeResult(IConditionProvider provider, RemoteException e) {
@@ -198,6 +217,8 @@ public class ZenLog {
            case TYPE_SET_NOTIFICATION_POLICY: return "set_notification_policy";
            case TYPE_SET_NOTIFICATION_POLICY: return "set_notification_policy";
            case TYPE_SET_CONSOLIDATED_ZEN_POLICY: return "set_consolidated_policy";
            case TYPE_SET_CONSOLIDATED_ZEN_POLICY: return "set_consolidated_policy";
            case TYPE_MATCHES_CALL_FILTER: return "matches_call_filter";
            case TYPE_MATCHES_CALL_FILTER: return "matches_call_filter";
            case TYPE_RECORD_CALLER: return "record_caller";
            case TYPE_CHECK_REPEAT_CALLER: return "check_repeat_caller";
            default: return "unknown";
            default: return "unknown";
        }
        }
    }
    }
+35 −13
Original line number Original line Diff line number Diff line
@@ -101,23 +101,24 @@ public class ZenModeFiltering {
     */
     */
    public static boolean matchesCallFilter(Context context, int zen, NotificationManager.Policy
    public static boolean matchesCallFilter(Context context, int zen, NotificationManager.Policy
            consolidatedPolicy, UserHandle userHandle, Bundle extras,
            consolidatedPolicy, UserHandle userHandle, Bundle extras,
            ValidateNotificationPeople validator, int contactsTimeoutMs, float timeoutAffinity) {
            ValidateNotificationPeople validator, int contactsTimeoutMs, float timeoutAffinity,
            int callingUid) {
        if (zen == Global.ZEN_MODE_NO_INTERRUPTIONS) {
        if (zen == Global.ZEN_MODE_NO_INTERRUPTIONS) {
            ZenLog.traceMatchesCallFilter(false, "no interruptions");
            ZenLog.traceMatchesCallFilter(false, "no interruptions", callingUid);
            return false; // nothing gets through
            return false; // nothing gets through
        }
        }
        if (zen == Global.ZEN_MODE_ALARMS) {
        if (zen == Global.ZEN_MODE_ALARMS) {
            ZenLog.traceMatchesCallFilter(false, "alarms only");
            ZenLog.traceMatchesCallFilter(false, "alarms only", callingUid);
            return false; // not an alarm
            return false; // not an alarm
        }
        }
        if (zen == Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS) {
        if (zen == Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS) {
            if (consolidatedPolicy.allowRepeatCallers()
            if (consolidatedPolicy.allowRepeatCallers()
                    && REPEAT_CALLERS.isRepeat(context, extras, null)) {
                    && REPEAT_CALLERS.isRepeat(context, extras, null)) {
                ZenLog.traceMatchesCallFilter(true, "repeat caller");
                ZenLog.traceMatchesCallFilter(true, "repeat caller", callingUid);
                return true;
                return true;
            }
            }
            if (!consolidatedPolicy.allowCalls()) {
            if (!consolidatedPolicy.allowCalls()) {
                ZenLog.traceMatchesCallFilter(false, "calls not allowed");
                ZenLog.traceMatchesCallFilter(false, "calls not allowed", callingUid);
                return false; // no other calls get through
                return false; // no other calls get through
            }
            }
            if (validator != null) {
            if (validator != null) {
@@ -125,11 +126,12 @@ public class ZenModeFiltering {
                        contactsTimeoutMs, timeoutAffinity);
                        contactsTimeoutMs, timeoutAffinity);
                boolean match =
                boolean match =
                        audienceMatches(consolidatedPolicy.allowCallsFrom(), contactAffinity);
                        audienceMatches(consolidatedPolicy.allowCallsFrom(), contactAffinity);
                ZenLog.traceMatchesCallFilter(match, "contact affinity " + contactAffinity);
                ZenLog.traceMatchesCallFilter(match, "contact affinity " + contactAffinity,
                        callingUid);
                return match;
                return match;
            }
            }
        }
        }
        ZenLog.traceMatchesCallFilter(true, "no restrictions");
        ZenLog.traceMatchesCallFilter(true, "no restrictions", callingUid);
        return true;
        return true;
    }
    }


@@ -419,6 +421,7 @@ public class ZenModeFiltering {


        private synchronized void recordCallers(String[] people, ArraySet<String> phoneNumbers,
        private synchronized void recordCallers(String[] people, ArraySet<String> phoneNumbers,
                long now) {
                long now) {
            boolean recorded = false, hasTel = false, hasOther = false;
            for (int i = 0; i < people.length; i++) {
            for (int i = 0; i < people.length; i++) {
                String person = people[i];
                String person = people[i];
                if (person == null) continue;
                if (person == null) continue;
@@ -427,10 +430,16 @@ public class ZenModeFiltering {
                    // while ideally we should not need to decode this, sometimes we have seen tel
                    // while ideally we should not need to decode this, sometimes we have seen tel
                    // numbers given in an encoded format
                    // numbers given in an encoded format
                    String tel = Uri.decode(uri.getSchemeSpecificPart());
                    String tel = Uri.decode(uri.getSchemeSpecificPart());
                    if (tel != null) mTelCalls.put(tel, now);
                    if (tel != null) {
                        mTelCalls.put(tel, now);
                        recorded = true;
                        hasTel = true;
                    }
                } else {
                } else {
                    // for non-tel calls, store the entire string, uri-component and all
                    // for non-tel calls, store the entire string, uri-component and all
                    mOtherCalls.put(person, now);
                    mOtherCalls.put(person, now);
                    recorded = true;
                    hasOther = true;
                }
                }
            }
            }


@@ -438,9 +447,16 @@ public class ZenModeFiltering {
            // provided; these are in the format of just a phone number string
            // provided; these are in the format of just a phone number string
            if (phoneNumbers != null) {
            if (phoneNumbers != null) {
                for (String num : phoneNumbers) {
                for (String num : phoneNumbers) {
                    if (num != null) mTelCalls.put(num, now);
                    if (num != null) {
                        mTelCalls.put(num, now);
                        recorded = true;
                        hasTel = true;
                    }
                }
                }
            }
            }
            if (recorded) {
                ZenLog.traceRecordCaller(hasTel, hasOther);
            }
        }
        }


        // helper function to check mTelCalls array for a number, and also check its decoded
        // helper function to check mTelCalls array for a number, and also check its decoded
@@ -468,6 +484,8 @@ public class ZenModeFiltering {
        // previously recorded phone call.
        // previously recorded phone call.
        private synchronized boolean checkCallers(Context context, String[] people,
        private synchronized boolean checkCallers(Context context, String[] people,
                ArraySet<String> phoneNumbers) {
                ArraySet<String> phoneNumbers) {
            boolean found = false, checkedTel = false, checkedOther = false;

            // get the default country code for checking telephone numbers
            // get the default country code for checking telephone numbers
            final String defaultCountryCode =
            final String defaultCountryCode =
                    context.getSystemService(TelephonyManager.class).getNetworkCountryIso();
                    context.getSystemService(TelephonyManager.class).getNetworkCountryIso();
@@ -477,12 +495,14 @@ public class ZenModeFiltering {
                final Uri uri = Uri.parse(person);
                final Uri uri = Uri.parse(person);
                if ("tel".equals(uri.getScheme())) {
                if ("tel".equals(uri.getScheme())) {
                    String number = uri.getSchemeSpecificPart();
                    String number = uri.getSchemeSpecificPart();
                    checkedTel = true;
                    if (checkForNumber(number, defaultCountryCode)) {
                    if (checkForNumber(number, defaultCountryCode)) {
                        return true;
                        found = true;
                    }
                    }
                } else {
                } else {
                    checkedOther = true;
                    if (mOtherCalls.containsKey(person)) {
                    if (mOtherCalls.containsKey(person)) {
                        return true;
                        found = true;
                    }
                    }
                }
                }
            }
            }
@@ -490,14 +510,16 @@ public class ZenModeFiltering {
            // also check any passed-in phone numbers
            // also check any passed-in phone numbers
            if (phoneNumbers != null) {
            if (phoneNumbers != null) {
                for (String num : phoneNumbers) {
                for (String num : phoneNumbers) {
                    checkedTel = true;
                    if (checkForNumber(num, defaultCountryCode)) {
                    if (checkForNumber(num, defaultCountryCode)) {
                        return true;
                        found = true;
                    }
                    }
                }
                }
            }
            }


            // no matches
            // no matches
            return false;
            ZenLog.traceCheckRepeatCaller(found, checkedTel, checkedOther);
            return found;
        }
        }
    }
    }


+4 −2
Original line number Original line Diff line number Diff line
@@ -177,10 +177,12 @@ public class ZenModeHelper {
    }
    }


    public boolean matchesCallFilter(UserHandle userHandle, Bundle extras,
    public boolean matchesCallFilter(UserHandle userHandle, Bundle extras,
            ValidateNotificationPeople validator, int contactsTimeoutMs, float timeoutAffinity) {
            ValidateNotificationPeople validator, int contactsTimeoutMs, float timeoutAffinity,
            int callingUid) {
        synchronized (mConfig) {
        synchronized (mConfig) {
            return ZenModeFiltering.matchesCallFilter(mContext, mZenMode, mConsolidatedPolicy,
            return ZenModeFiltering.matchesCallFilter(mContext, mZenMode, mConsolidatedPolicy,
                    userHandle, extras, validator, contactsTimeoutMs, timeoutAffinity);
                    userHandle, extras, validator, contactsTimeoutMs, timeoutAffinity,
                    callingUid);
        }
        }
    }
    }


+15 −15
Original line number Original line Diff line number Diff line
@@ -8,7 +8,7 @@
 *      http://www.apache.org/licenses/LICENSE-2.0
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *
 * Unless required by applicable law or agreed to in writing, software
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distriZenbuted on an "AS IS" BASIS,
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * limitations under the License.
@@ -397,10 +397,10 @@ public class ZenModeFilteringTest extends UiServiceTestCase {
        Bundle inputWrong = makeExtrasBundleWithPeople(new String[]{"mailto:nope"});
        Bundle inputWrong = makeExtrasBundleWithPeople(new String[]{"mailto:nope"});
        assertTrue(ZenModeFiltering.matchesCallFilter(mContext, ZEN_MODE_IMPORTANT_INTERRUPTIONS,
        assertTrue(ZenModeFiltering.matchesCallFilter(mContext, ZEN_MODE_IMPORTANT_INTERRUPTIONS,
                policy, UserHandle.SYSTEM,
                policy, UserHandle.SYSTEM,
                inputMatches, null, 0, 0));
                inputMatches, null, 0, 0, 0));
        assertFalse(ZenModeFiltering.matchesCallFilter(mContext, ZEN_MODE_IMPORTANT_INTERRUPTIONS,
        assertFalse(ZenModeFiltering.matchesCallFilter(mContext, ZEN_MODE_IMPORTANT_INTERRUPTIONS,
                policy, UserHandle.SYSTEM,
                policy, UserHandle.SYSTEM,
                inputWrong, null, 0, 0));
                inputWrong, null, 0, 0, 0));
    }
    }


    @Test
    @Test
@@ -428,19 +428,19 @@ public class ZenModeFilteringTest extends UiServiceTestCase {
        assertTrue("identical numbers should match",
        assertTrue("identical numbers should match",
                ZenModeFiltering.matchesCallFilter(mContext, ZEN_MODE_IMPORTANT_INTERRUPTIONS,
                ZenModeFiltering.matchesCallFilter(mContext, ZEN_MODE_IMPORTANT_INTERRUPTIONS,
                policy, UserHandle.SYSTEM,
                policy, UserHandle.SYSTEM,
                identical, null, 0, 0));
                identical, null, 0, 0, 0));
        assertTrue("equivalent but non-identical numbers should match",
        assertTrue("equivalent but non-identical numbers should match",
                ZenModeFiltering.matchesCallFilter(mContext, ZEN_MODE_IMPORTANT_INTERRUPTIONS,
                ZenModeFiltering.matchesCallFilter(mContext, ZEN_MODE_IMPORTANT_INTERRUPTIONS,
                policy, UserHandle.SYSTEM,
                policy, UserHandle.SYSTEM,
                same, null, 0, 0));
                same, null, 0, 0, 0));
        assertFalse("non-equivalent numbers should not match",
        assertFalse("non-equivalent numbers should not match",
                ZenModeFiltering.matchesCallFilter(mContext, ZEN_MODE_IMPORTANT_INTERRUPTIONS,
                ZenModeFiltering.matchesCallFilter(mContext, ZEN_MODE_IMPORTANT_INTERRUPTIONS,
                policy, UserHandle.SYSTEM,
                policy, UserHandle.SYSTEM,
                different, null, 0, 0));
                different, null, 0, 0, 0));
        assertFalse("non-tel strings should not match",
        assertFalse("non-tel strings should not match",
                ZenModeFiltering.matchesCallFilter(mContext, ZEN_MODE_IMPORTANT_INTERRUPTIONS,
                ZenModeFiltering.matchesCallFilter(mContext, ZEN_MODE_IMPORTANT_INTERRUPTIONS,
                policy, UserHandle.SYSTEM,
                policy, UserHandle.SYSTEM,
                garbage, null, 0, 0));
                garbage, null, 0, 0, 0));
    }
    }


    @Test
    @Test
@@ -469,23 +469,23 @@ public class ZenModeFilteringTest extends UiServiceTestCase {
        assertTrue("same number 1 should match",
        assertTrue("same number 1 should match",
                ZenModeFiltering.matchesCallFilter(mContext, ZEN_MODE_IMPORTANT_INTERRUPTIONS,
                ZenModeFiltering.matchesCallFilter(mContext, ZEN_MODE_IMPORTANT_INTERRUPTIONS,
                        policy, UserHandle.SYSTEM,
                        policy, UserHandle.SYSTEM,
                        same1, null, 0, 0));
                        same1, null, 0, 0, 0));
        assertTrue("same number 2 should match",
        assertTrue("same number 2 should match",
                ZenModeFiltering.matchesCallFilter(mContext, ZEN_MODE_IMPORTANT_INTERRUPTIONS,
                ZenModeFiltering.matchesCallFilter(mContext, ZEN_MODE_IMPORTANT_INTERRUPTIONS,
                        policy, UserHandle.SYSTEM,
                        policy, UserHandle.SYSTEM,
                        same2, null, 0, 0));
                        same2, null, 0, 0, 0));
        assertTrue("same number 3 should match",
        assertTrue("same number 3 should match",
                ZenModeFiltering.matchesCallFilter(mContext, ZEN_MODE_IMPORTANT_INTERRUPTIONS,
                ZenModeFiltering.matchesCallFilter(mContext, ZEN_MODE_IMPORTANT_INTERRUPTIONS,
                        policy, UserHandle.SYSTEM,
                        policy, UserHandle.SYSTEM,
                        same3, null, 0, 0));
                        same3, null, 0, 0, 0));
        assertFalse("different number 1 should not match",
        assertFalse("different number 1 should not match",
                ZenModeFiltering.matchesCallFilter(mContext, ZEN_MODE_IMPORTANT_INTERRUPTIONS,
                ZenModeFiltering.matchesCallFilter(mContext, ZEN_MODE_IMPORTANT_INTERRUPTIONS,
                        policy, UserHandle.SYSTEM,
                        policy, UserHandle.SYSTEM,
                        different1, null, 0, 0));
                        different1, null, 0, 0, 0));
        assertFalse("different number 2 should not match",
        assertFalse("different number 2 should not match",
                ZenModeFiltering.matchesCallFilter(mContext, ZEN_MODE_IMPORTANT_INTERRUPTIONS,
                ZenModeFiltering.matchesCallFilter(mContext, ZEN_MODE_IMPORTANT_INTERRUPTIONS,
                        policy, UserHandle.SYSTEM,
                        policy, UserHandle.SYSTEM,
                        different2, null, 0, 0));
                        different2, null, 0, 0, 0));
    }
    }


    @Test
    @Test
@@ -516,14 +516,14 @@ public class ZenModeFilteringTest extends UiServiceTestCase {
        assertTrue("contact number 1 should match",
        assertTrue("contact number 1 should match",
                ZenModeFiltering.matchesCallFilter(mContext, ZEN_MODE_IMPORTANT_INTERRUPTIONS,
                ZenModeFiltering.matchesCallFilter(mContext, ZEN_MODE_IMPORTANT_INTERRUPTIONS,
                        policy, UserHandle.SYSTEM,
                        policy, UserHandle.SYSTEM,
                        tel1, null, 0, 0));
                        tel1, null, 0, 0, 0));
        assertTrue("contact number 2 should match",
        assertTrue("contact number 2 should match",
                ZenModeFiltering.matchesCallFilter(mContext, ZEN_MODE_IMPORTANT_INTERRUPTIONS,
                ZenModeFiltering.matchesCallFilter(mContext, ZEN_MODE_IMPORTANT_INTERRUPTIONS,
                        policy, UserHandle.SYSTEM,
                        policy, UserHandle.SYSTEM,
                        tel2, null, 0, 0));
                        tel2, null, 0, 0, 0));
        assertFalse("different number should not match",
        assertFalse("different number should not match",
                ZenModeFiltering.matchesCallFilter(mContext, ZEN_MODE_IMPORTANT_INTERRUPTIONS,
                ZenModeFiltering.matchesCallFilter(mContext, ZEN_MODE_IMPORTANT_INTERRUPTIONS,
                        policy, UserHandle.SYSTEM,
                        policy, UserHandle.SYSTEM,
                        different, null, 0, 0));
                        different, null, 0, 0, 0));
    }
    }
}
}