Loading src/com/android/server/telecom/ui/MissedCallNotifierImpl.java +47 −11 Original line number Diff line number Diff line Loading @@ -28,6 +28,7 @@ import android.app.TaskStackBuilder; import android.app.admin.DevicePolicyManager; import android.content.AsyncQueryHandler; import android.content.ContentProvider; import android.content.ContentResolver; import android.content.ContentValues; import android.content.Context; import android.content.Intent; Loading Loading @@ -108,7 +109,8 @@ public class MissedCallNotifierImpl extends CallsManagerListenerBase implements } } private static final String[] CALL_LOG_PROJECTION = new String[] { @VisibleForTesting public static final String[] CALL_LOG_PROJECTION = new String[] { Calls._ID, Calls.NUMBER, Calls.NUMBER_PRESENTATION, Loading @@ -117,7 +119,8 @@ public class MissedCallNotifierImpl extends CallsManagerListenerBase implements Calls.TYPE, }; private static final String CALL_LOG_WHERE_CLAUSE = "type=" + Calls.MISSED_TYPE + @VisibleForTesting public static final String CALL_LOG_WHERE_CLAUSE = "type=" + Calls.MISSED_TYPE + " AND new=1" + " AND is_read=0"; Loading Loading @@ -197,14 +200,35 @@ public class MissedCallNotifierImpl extends CallsManagerListenerBase implements where.append(Calls.TYPE); where.append(" = ?"); try { Uri callsUri = ContentProvider ContentResolver resolver; Uri uriToUpdate; if (mFeatureFlags.resolveHiddenDependenciesTwo()) { Context userContext = mContext.createContextAsUser(userHandle, 0); resolver = userContext.getContentResolver(); uriToUpdate = Calls.CONTENT_URI; } else { resolver = mContext.getContentResolver(); uriToUpdate = ContentProvider .maybeAddUserId(Calls.CONTENT_URI, userHandle.getIdentifier()); mContext.getContentResolver().update(callsUri, values, where.toString(), new String[]{ Integer.toString(Calls. MISSED_TYPE) }); } if (resolver != null && uriToUpdate != null) { resolver.update(uriToUpdate, values, where.toString(), new String[]{ Integer.toString(Calls.MISSED_TYPE) }); } else { Log.w(this, "markMissedCallsAsRead: ContentResolver or UriToUpdate " + "is null. Cannot update call log. Resolver: " + resolver + " Uri: " + uriToUpdate); } } catch (IllegalArgumentException e) { Log.w(this, "ContactsProvider update command failed", e); Log.e(this, e, "ContactsProvider update command failed for user " + userHandle); } catch (Exception e) { Log.e(this, e, "Exception in markMissedCallsAsRead for user " + userHandle); } } }.prepare()); } Loading Loading @@ -631,8 +655,15 @@ public class MissedCallNotifierImpl extends CallsManagerListenerBase implements return; } Context contextToUse; if (mFeatureFlags.resolveHiddenDependenciesTwo()) { contextToUse = mContext.createContextAsUser(userHandle, 0 /* flags */); } else { contextToUse = mContext; } // instantiate query handler AsyncQueryHandler queryHandler = new AsyncQueryHandler(mContext.getContentResolver()) { AsyncQueryHandler queryHandler = new AsyncQueryHandler(contextToUse.getContentResolver()) { @Override protected void onQueryComplete(int token, Object cookie, Cursor cursor) { Log.d(MissedCallNotifierImpl.this, "onQueryComplete()..."); Loading Loading @@ -713,8 +744,13 @@ public class MissedCallNotifierImpl extends CallsManagerListenerBase implements }; // setup query spec, look for all Missed calls that are new. Uri callsUri = ContentProvider.maybeAddUserId(Calls.CONTENT_URI, userHandle.getIdentifier()); Uri callsUri; if (mFeatureFlags.resolveHiddenDependenciesTwo()) { callsUri = Calls.CONTENT_URI; } else { callsUri = ContentProvider .maybeAddUserId(Calls.CONTENT_URI, userHandle.getIdentifier()); } // start the query queryHandler.startQuery(0, null, callsUri, CALL_LOG_PROJECTION, CALL_LOG_WHERE_CLAUSE, null, Calls.DEFAULT_SORT_ORDER); Loading tests/src/com/android/server/telecom/tests/MissedCallNotifierImplTest.java +23 −16 Original line number Diff line number Diff line Loading @@ -46,6 +46,7 @@ import android.app.NotificationManager; import android.app.PendingIntent; import android.content.ComponentName; import android.content.ContentProvider; import android.content.ContentResolver; import android.content.Context; import android.content.IContentProvider; import android.content.Intent; Loading Loading @@ -173,6 +174,7 @@ public class MissedCallNotifierImplTest extends TelecomTestCase { @Mock private DefaultDialerCache mDefaultDialerCache; @Mock private DeviceIdleControllerAdapter mDeviceIdleControllerAdapter; @Mock private Context mUserContext; @Mock private ContentResolver mUserContentResolver; @Override @Before Loading @@ -187,6 +189,7 @@ public class MissedCallNotifierImplTest extends TelecomTestCase { .thenReturn(mUserContext); when(mUserContext.getSystemService(eq(NotificationManager.class))) .thenReturn(mNotificationManager); when(mUserContext.getContentResolver()).thenReturn(mUserContentResolver); TelephonyManager fakeTelephonyManager = (TelephonyManager) mContext.getSystemService( Context.TELEPHONY_SERVICE); when(fakeTelephonyManager.getNetworkCountryIso()).thenReturn("US"); Loading Loading @@ -528,19 +531,20 @@ public class MissedCallNotifierImplTest extends TelecomTestCase { CallerInfoLookupHelper mockCallerInfoLookupHelper = mock(CallerInfoLookupHelper.class); MissedCallNotifier.CallInfoFactory mockCallInfoFactory = mock(MissedCallNotifier.CallInfoFactory.class); Uri queryUri = ContentProvider.maybeAddUserId(CallLog.Calls.CONTENT_URI, PRIMARY_USER.getIdentifier()); IContentProvider cp = getContentProviderForUser(PRIMARY_USER.getIdentifier()); Uri expectedQueryUri = CallLog.Calls.CONTENT_URI; Cursor mockMissedCallsCursor = new MockMissedCallCursorBuilder() .addEntry(TEL_CALL_HANDLE.getSchemeSpecificPart(), CallLog.Calls.PRESENTATION_ALLOWED, CALL_TIMESTAMP) .build(); when(cp.query(any(), eq(queryUri), nullable(String[].class), nullable(Bundle.class), nullable(ICancellationSignal.class))) .thenReturn(mockMissedCallsCursor); when(mUserContentResolver.query( eq(expectedQueryUri), eq(MissedCallNotifierImpl.CALL_LOG_PROJECTION), eq(MissedCallNotifierImpl.CALL_LOG_WHERE_CLAUSE), isNull(), // selectionArgs is null in MissedCallNotifierImpl eq(CallLog.Calls.DEFAULT_SORT_ORDER) )).thenReturn(mockMissedCallsCursor); PhoneAccount phoneAccount = makePhoneAccount(PRIMARY_USER, NO_CAPABILITY); MissedCallNotifier.CallInfo fakeCallInfo = makeFakeCallInfo(TEL_CALL_HANDLE, Loading @@ -553,9 +557,10 @@ public class MissedCallNotifierImplTest extends TelecomTestCase { MissedCallNotifierImpl.NotificationBuilderFactory fakeBuilderFactory = makeNotificationBuilderFactory(builder1); MissedCallNotifier missedCallNotifier = new MissedCallNotifierImpl(mContext, MissedCallNotifierImpl missedCallNotifier = new MissedCallNotifierImpl(mContext, mPhoneAccountRegistrar, mDefaultDialerCache, fakeBuilderFactory, mDeviceIdleControllerAdapter, mFeatureFlags); missedCallNotifier.setCurrentUserHandle(PRIMARY_USER); // AsyncQueryHandler used in reloadFromDatabase interacts poorly with the below // timeout-verify, so run this in a new handler to mitigate that. Loading Loading @@ -604,13 +609,14 @@ public class MissedCallNotifierImplTest extends TelecomTestCase { CallLog.Calls.PRESENTATION_ALLOWED, CALL_TIMESTAMP) .build(); Uri queryUri = ContentProvider.maybeAddUserId(CallLog.Calls.CONTENT_URI, PRIMARY_USER.getIdentifier()); IContentProvider cp = getContentProviderForUser(PRIMARY_USER.getIdentifier()); when(cp.query(any(), eq(queryUri), nullable(String[].class), nullable(Bundle.class), nullable(ICancellationSignal.class))) .thenReturn(mockMissedCallsCursor); Uri expectedQueryUri = CallLog.Calls.CONTENT_URI; when(mUserContentResolver.query( eq(expectedQueryUri), eq(MissedCallNotifierImpl.CALL_LOG_PROJECTION), eq(MissedCallNotifierImpl.CALL_LOG_WHERE_CLAUSE), isNull(), eq(CallLog.Calls.DEFAULT_SORT_ORDER) )).thenReturn(mockMissedCallsCursor); PhoneAccount phoneAccount = makePhoneAccount(PRIMARY_USER, NO_CAPABILITY); MissedCallNotifier.CallInfo fakeCallInfo = makeFakeCallInfo(TEL_CALL_HANDLE, Loading @@ -623,9 +629,10 @@ public class MissedCallNotifierImplTest extends TelecomTestCase { MissedCallNotifierImpl.NotificationBuilderFactory fakeBuilderFactory = makeNotificationBuilderFactory(builder1); MissedCallNotifier missedCallNotifier = new MissedCallNotifierImpl(mContext, MissedCallNotifierImpl missedCallNotifier = new MissedCallNotifierImpl(mContext, mPhoneAccountRegistrar, mDefaultDialerCache, fakeBuilderFactory, mDeviceIdleControllerAdapter, mFeatureFlags); missedCallNotifier.setCurrentUserHandle(PRIMARY_USER); // AsyncQueryHandler used in reloadFromDatabase interacts poorly with the below // timeout-verify, so run this in a new handler to mitigate that. Loading Loading
src/com/android/server/telecom/ui/MissedCallNotifierImpl.java +47 −11 Original line number Diff line number Diff line Loading @@ -28,6 +28,7 @@ import android.app.TaskStackBuilder; import android.app.admin.DevicePolicyManager; import android.content.AsyncQueryHandler; import android.content.ContentProvider; import android.content.ContentResolver; import android.content.ContentValues; import android.content.Context; import android.content.Intent; Loading Loading @@ -108,7 +109,8 @@ public class MissedCallNotifierImpl extends CallsManagerListenerBase implements } } private static final String[] CALL_LOG_PROJECTION = new String[] { @VisibleForTesting public static final String[] CALL_LOG_PROJECTION = new String[] { Calls._ID, Calls.NUMBER, Calls.NUMBER_PRESENTATION, Loading @@ -117,7 +119,8 @@ public class MissedCallNotifierImpl extends CallsManagerListenerBase implements Calls.TYPE, }; private static final String CALL_LOG_WHERE_CLAUSE = "type=" + Calls.MISSED_TYPE + @VisibleForTesting public static final String CALL_LOG_WHERE_CLAUSE = "type=" + Calls.MISSED_TYPE + " AND new=1" + " AND is_read=0"; Loading Loading @@ -197,14 +200,35 @@ public class MissedCallNotifierImpl extends CallsManagerListenerBase implements where.append(Calls.TYPE); where.append(" = ?"); try { Uri callsUri = ContentProvider ContentResolver resolver; Uri uriToUpdate; if (mFeatureFlags.resolveHiddenDependenciesTwo()) { Context userContext = mContext.createContextAsUser(userHandle, 0); resolver = userContext.getContentResolver(); uriToUpdate = Calls.CONTENT_URI; } else { resolver = mContext.getContentResolver(); uriToUpdate = ContentProvider .maybeAddUserId(Calls.CONTENT_URI, userHandle.getIdentifier()); mContext.getContentResolver().update(callsUri, values, where.toString(), new String[]{ Integer.toString(Calls. MISSED_TYPE) }); } if (resolver != null && uriToUpdate != null) { resolver.update(uriToUpdate, values, where.toString(), new String[]{ Integer.toString(Calls.MISSED_TYPE) }); } else { Log.w(this, "markMissedCallsAsRead: ContentResolver or UriToUpdate " + "is null. Cannot update call log. Resolver: " + resolver + " Uri: " + uriToUpdate); } } catch (IllegalArgumentException e) { Log.w(this, "ContactsProvider update command failed", e); Log.e(this, e, "ContactsProvider update command failed for user " + userHandle); } catch (Exception e) { Log.e(this, e, "Exception in markMissedCallsAsRead for user " + userHandle); } } }.prepare()); } Loading Loading @@ -631,8 +655,15 @@ public class MissedCallNotifierImpl extends CallsManagerListenerBase implements return; } Context contextToUse; if (mFeatureFlags.resolveHiddenDependenciesTwo()) { contextToUse = mContext.createContextAsUser(userHandle, 0 /* flags */); } else { contextToUse = mContext; } // instantiate query handler AsyncQueryHandler queryHandler = new AsyncQueryHandler(mContext.getContentResolver()) { AsyncQueryHandler queryHandler = new AsyncQueryHandler(contextToUse.getContentResolver()) { @Override protected void onQueryComplete(int token, Object cookie, Cursor cursor) { Log.d(MissedCallNotifierImpl.this, "onQueryComplete()..."); Loading Loading @@ -713,8 +744,13 @@ public class MissedCallNotifierImpl extends CallsManagerListenerBase implements }; // setup query spec, look for all Missed calls that are new. Uri callsUri = ContentProvider.maybeAddUserId(Calls.CONTENT_URI, userHandle.getIdentifier()); Uri callsUri; if (mFeatureFlags.resolveHiddenDependenciesTwo()) { callsUri = Calls.CONTENT_URI; } else { callsUri = ContentProvider .maybeAddUserId(Calls.CONTENT_URI, userHandle.getIdentifier()); } // start the query queryHandler.startQuery(0, null, callsUri, CALL_LOG_PROJECTION, CALL_LOG_WHERE_CLAUSE, null, Calls.DEFAULT_SORT_ORDER); Loading
tests/src/com/android/server/telecom/tests/MissedCallNotifierImplTest.java +23 −16 Original line number Diff line number Diff line Loading @@ -46,6 +46,7 @@ import android.app.NotificationManager; import android.app.PendingIntent; import android.content.ComponentName; import android.content.ContentProvider; import android.content.ContentResolver; import android.content.Context; import android.content.IContentProvider; import android.content.Intent; Loading Loading @@ -173,6 +174,7 @@ public class MissedCallNotifierImplTest extends TelecomTestCase { @Mock private DefaultDialerCache mDefaultDialerCache; @Mock private DeviceIdleControllerAdapter mDeviceIdleControllerAdapter; @Mock private Context mUserContext; @Mock private ContentResolver mUserContentResolver; @Override @Before Loading @@ -187,6 +189,7 @@ public class MissedCallNotifierImplTest extends TelecomTestCase { .thenReturn(mUserContext); when(mUserContext.getSystemService(eq(NotificationManager.class))) .thenReturn(mNotificationManager); when(mUserContext.getContentResolver()).thenReturn(mUserContentResolver); TelephonyManager fakeTelephonyManager = (TelephonyManager) mContext.getSystemService( Context.TELEPHONY_SERVICE); when(fakeTelephonyManager.getNetworkCountryIso()).thenReturn("US"); Loading Loading @@ -528,19 +531,20 @@ public class MissedCallNotifierImplTest extends TelecomTestCase { CallerInfoLookupHelper mockCallerInfoLookupHelper = mock(CallerInfoLookupHelper.class); MissedCallNotifier.CallInfoFactory mockCallInfoFactory = mock(MissedCallNotifier.CallInfoFactory.class); Uri queryUri = ContentProvider.maybeAddUserId(CallLog.Calls.CONTENT_URI, PRIMARY_USER.getIdentifier()); IContentProvider cp = getContentProviderForUser(PRIMARY_USER.getIdentifier()); Uri expectedQueryUri = CallLog.Calls.CONTENT_URI; Cursor mockMissedCallsCursor = new MockMissedCallCursorBuilder() .addEntry(TEL_CALL_HANDLE.getSchemeSpecificPart(), CallLog.Calls.PRESENTATION_ALLOWED, CALL_TIMESTAMP) .build(); when(cp.query(any(), eq(queryUri), nullable(String[].class), nullable(Bundle.class), nullable(ICancellationSignal.class))) .thenReturn(mockMissedCallsCursor); when(mUserContentResolver.query( eq(expectedQueryUri), eq(MissedCallNotifierImpl.CALL_LOG_PROJECTION), eq(MissedCallNotifierImpl.CALL_LOG_WHERE_CLAUSE), isNull(), // selectionArgs is null in MissedCallNotifierImpl eq(CallLog.Calls.DEFAULT_SORT_ORDER) )).thenReturn(mockMissedCallsCursor); PhoneAccount phoneAccount = makePhoneAccount(PRIMARY_USER, NO_CAPABILITY); MissedCallNotifier.CallInfo fakeCallInfo = makeFakeCallInfo(TEL_CALL_HANDLE, Loading @@ -553,9 +557,10 @@ public class MissedCallNotifierImplTest extends TelecomTestCase { MissedCallNotifierImpl.NotificationBuilderFactory fakeBuilderFactory = makeNotificationBuilderFactory(builder1); MissedCallNotifier missedCallNotifier = new MissedCallNotifierImpl(mContext, MissedCallNotifierImpl missedCallNotifier = new MissedCallNotifierImpl(mContext, mPhoneAccountRegistrar, mDefaultDialerCache, fakeBuilderFactory, mDeviceIdleControllerAdapter, mFeatureFlags); missedCallNotifier.setCurrentUserHandle(PRIMARY_USER); // AsyncQueryHandler used in reloadFromDatabase interacts poorly with the below // timeout-verify, so run this in a new handler to mitigate that. Loading Loading @@ -604,13 +609,14 @@ public class MissedCallNotifierImplTest extends TelecomTestCase { CallLog.Calls.PRESENTATION_ALLOWED, CALL_TIMESTAMP) .build(); Uri queryUri = ContentProvider.maybeAddUserId(CallLog.Calls.CONTENT_URI, PRIMARY_USER.getIdentifier()); IContentProvider cp = getContentProviderForUser(PRIMARY_USER.getIdentifier()); when(cp.query(any(), eq(queryUri), nullable(String[].class), nullable(Bundle.class), nullable(ICancellationSignal.class))) .thenReturn(mockMissedCallsCursor); Uri expectedQueryUri = CallLog.Calls.CONTENT_URI; when(mUserContentResolver.query( eq(expectedQueryUri), eq(MissedCallNotifierImpl.CALL_LOG_PROJECTION), eq(MissedCallNotifierImpl.CALL_LOG_WHERE_CLAUSE), isNull(), eq(CallLog.Calls.DEFAULT_SORT_ORDER) )).thenReturn(mockMissedCallsCursor); PhoneAccount phoneAccount = makePhoneAccount(PRIMARY_USER, NO_CAPABILITY); MissedCallNotifier.CallInfo fakeCallInfo = makeFakeCallInfo(TEL_CALL_HANDLE, Loading @@ -623,9 +629,10 @@ public class MissedCallNotifierImplTest extends TelecomTestCase { MissedCallNotifierImpl.NotificationBuilderFactory fakeBuilderFactory = makeNotificationBuilderFactory(builder1); MissedCallNotifier missedCallNotifier = new MissedCallNotifierImpl(mContext, MissedCallNotifierImpl missedCallNotifier = new MissedCallNotifierImpl(mContext, mPhoneAccountRegistrar, mDefaultDialerCache, fakeBuilderFactory, mDeviceIdleControllerAdapter, mFeatureFlags); missedCallNotifier.setCurrentUserHandle(PRIMARY_USER); // AsyncQueryHandler used in reloadFromDatabase interacts poorly with the below // timeout-verify, so run this in a new handler to mitigate that. Loading