Merge "Dereference cached Bitmaps in EventLogger"
diff --git a/src/com/android/server/telecom/DefaultDialerCache.java b/src/com/android/server/telecom/DefaultDialerCache.java
index 9f7be16..3b36119 100644
--- a/src/com/android/server/telecom/DefaultDialerCache.java
+++ b/src/com/android/server/telecom/DefaultDialerCache.java
@@ -91,6 +91,22 @@
}
};
+ private final BroadcastReceiver mUserRemovedReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (Intent.ACTION_USER_REMOVED.equals(intent.getAction())) {
+ int removedUser = intent.getIntExtra(Intent.EXTRA_USER_HANDLE,
+ UserHandle.USER_NULL);
+ if (removedUser == UserHandle.USER_NULL) {
+ Log.w(LOG_TAG, "Expected EXTRA_USER_HANDLE with ACTION_USER_REMOVED");
+ } else {
+ removeUserFromCache(removedUser);
+ Log.i(LOG_TAG, "Removing user %s", removedUser);
+ }
+ }
+ }
+ };
+
private final Handler mHandler = new Handler(Looper.getMainLooper());
private final ContentObserver mDefaultDialerObserver = new ContentObserver(mHandler) {
@Override
@@ -137,6 +153,8 @@
IntentFilter bootIntentFilter = new IntentFilter(Intent.ACTION_BOOT_COMPLETED);
context.registerReceiverAsUser(mReceiver, UserHandle.ALL, bootIntentFilter, null, null);
+ IntentFilter userRemovedFilter = new IntentFilter(Intent.ACTION_USER_REMOVED);
+ context.registerReceiver(mUserRemovedReceiver, userRemovedFilter);
Uri defaultDialerSetting =
Settings.Secure.getUriFor(Settings.Secure.DIALER_DEFAULT_APPLICATION);
@@ -221,6 +239,12 @@
}
}
+ private void removeUserFromCache(int userId) {
+ synchronized (mLock) {
+ mCurrentDefaultDialerPerUser.remove(userId);
+ }
+ }
+
/**
* registerContentObserver is really hard to mock out, so here is a getter method for the
* content observer for testing instead.
diff --git a/src/com/android/server/telecom/TelecomServiceImpl.java b/src/com/android/server/telecom/TelecomServiceImpl.java
index 40ba21d..72cf998 100644
--- a/src/com/android/server/telecom/TelecomServiceImpl.java
+++ b/src/com/android/server/telecom/TelecomServiceImpl.java
@@ -79,6 +79,7 @@
}
}
+ private static final String TIME_LINE_ARG = "timeline";
private static final int DEFAULT_VIDEO_STATE = -1;
private final ITelecomService.Stub mBinderImpl = new ITelecomService.Stub() {
@@ -996,6 +997,10 @@
android.Manifest.permission.MANAGE_OWN_CALLS,
"Self-managed phone accounts must have MANAGE_OWN_CALLS " +
"permission.");
+
+ // Self-managed ConnectionServices can ONLY add new incoming calls
+ // using their own PhoneAccounts. The checkPackage(..) app opps
+ // check above ensures this.
}
}
long token = Binder.clearCallingIdentity();
@@ -1086,6 +1091,16 @@
if (isSelfManaged) {
mContext.enforceCallingOrSelfPermission(Manifest.permission.MANAGE_OWN_CALLS,
"Self-managed ConnectionServices require MANAGE_OWN_CALLS permission.");
+
+ if (!callingPackage.equals(
+ phoneAccountHandle.getComponentName().getPackageName())
+ && !canCallPhone(callingPackage,
+ "CALL_PHONE permission required to place calls.")) {
+ // The caller is not allowed to place calls, so we want to ensure that it
+ // can only place calls through itself.
+ throw new SecurityException("Self-managed ConnectionServices can only "
+ + "place calls through their own ConnectionService.");
+ }
} else if (!canCallPhone(callingPackage, "placeCall")) {
throw new SecurityException("Package " + callingPackage
+ " is not allowed to place phone calls");
@@ -1210,6 +1225,7 @@
Analytics.dumpToEncodedProto(writer, args);
return;
}
+ boolean isTimeLineView = (args.length > 0 && TIME_LINE_ARG.equalsIgnoreCase(args[0]));
final IndentingPrintWriter pw = new IndentingPrintWriter(writer, " ");
if (mCallsManager != null) {
@@ -1228,8 +1244,11 @@
Analytics.dump(pw);
pw.decreaseIndent();
}
-
- Log.dumpEvents(pw);
+ if (isTimeLineView) {
+ Log.dumpEventsTimeline(pw);
+ } else {
+ Log.dumpEvents(pw);
+ }
}
/**
diff --git a/tests/src/com/android/server/telecom/tests/DefaultDialerCacheTest.java b/tests/src/com/android/server/telecom/tests/DefaultDialerCacheTest.java
index e73df61..82fee3e 100644
--- a/tests/src/com/android/server/telecom/tests/DefaultDialerCacheTest.java
+++ b/tests/src/com/android/server/telecom/tests/DefaultDialerCacheTest.java
@@ -51,6 +51,7 @@
private DefaultDialerCache mDefaultDialerCache;
private ContentObserver mDefaultDialerSettingObserver;
private BroadcastReceiver mPackageChangeReceiver;
+ private BroadcastReceiver mUserRemovedReceiver;
@Mock private DefaultDialerCache.DefaultDialerManagerAdapter mMockDefaultDialerManager;
@@ -58,17 +59,24 @@
super.setUp();
mContext = mComponentContextFixture.getTestDouble().getApplicationContext();
- ArgumentCaptor<BroadcastReceiver> receiverCaptor =
+ ArgumentCaptor<BroadcastReceiver> packageReceiverCaptor =
ArgumentCaptor.forClass(BroadcastReceiver.class);
mDefaultDialerCache = new DefaultDialerCache(
mContext, mMockDefaultDialerManager, new TelecomSystem.SyncRoot() { });
verify(mContext, times(2)).registerReceiverAsUser(
- receiverCaptor.capture(), eq(UserHandle.ALL), any(IntentFilter.class),
+ packageReceiverCaptor.capture(), eq(UserHandle.ALL), any(IntentFilter.class),
isNull(String.class), isNull(Handler.class));
// Receive the first receiver that was captured, the package change receiver.
- mPackageChangeReceiver = receiverCaptor.getAllValues().get(0);
+ mPackageChangeReceiver = packageReceiverCaptor.getAllValues().get(0);
+
+ ArgumentCaptor<BroadcastReceiver> userRemovedReceiverCaptor =
+ ArgumentCaptor.forClass(BroadcastReceiver.class);
+ verify(mContext).registerReceiver(
+ userRemovedReceiverCaptor.capture(), any(IntentFilter.class));
+ mUserRemovedReceiver = userRemovedReceiverCaptor.getAllValues().get(0);
+
mDefaultDialerSettingObserver = mDefaultDialerCache.getContentObserver();
when(mMockDefaultDialerManager.getDefaultDialerApplication(any(Context.class), eq(USER0)))
@@ -138,6 +146,24 @@
}
@SmallTest
+ public void testUserRemoved() {
+ assertEquals(mDefaultDialerCache.getDefaultDialerApplication(USER0), DIALER1);
+ assertEquals(mDefaultDialerCache.getDefaultDialerApplication(USER1), DIALER2);
+
+ Intent userRemovalIntent = new Intent(Intent.ACTION_USER_REMOVED);
+ userRemovalIntent.putExtra(Intent.EXTRA_USER_HANDLE, USER0);
+ mUserRemovedReceiver.onReceive(mContext, userRemovalIntent);
+
+ assertEquals(mDefaultDialerCache.getDefaultDialerApplication(USER0), DIALER1);
+ assertEquals(mDefaultDialerCache.getDefaultDialerApplication(USER1), DIALER2);
+
+ verify(mMockDefaultDialerManager, times(2))
+ .getDefaultDialerApplication(any(Context.class), eq(USER0));
+ verify(mMockDefaultDialerManager, times(1))
+ .getDefaultDialerApplication(any(Context.class), eq(USER1));
+ }
+
+ @SmallTest
public void testPackageRemovedWithoutReplace() {
assertEquals(mDefaultDialerCache.getDefaultDialerApplication(USER0), DIALER1);
assertEquals(mDefaultDialerCache.getDefaultDialerApplication(USER1), DIALER2);