summaryrefslogtreecommitdiffstats
path: root/src/com
diff options
context:
space:
mode:
authorSailesh Nepal <sail@google.com>2015-02-14 15:44:55 -0800
committerEtan Cohen <etancohen@google.com>2015-03-02 11:31:23 -0800
commit91fc8099a0690a3367eb206788c9c25ceff31875 (patch)
tree628c5215b3a8dc06ed6dd077747ef42f5ce67d78 /src/com
parent78a5e6b9c1595c81f72d7a822617cb78db224e48 (diff)
downloadandroid_packages_services_Telecomm-91fc8099a0690a3367eb206788c9c25ceff31875.tar.gz
android_packages_services_Telecomm-91fc8099a0690a3367eb206788c9c25ceff31875.tar.bz2
android_packages_services_Telecomm-91fc8099a0690a3367eb206788c9c25ceff31875.zip
Fix connection manager bugs related to work profiles
When calling TelecomManager.addNewIncomingCall with an account that's was not registered we would crash. Fix was to check for a null phone account. Various TelecomManager APIs would throw security exceptions when called from a work profile. Fix was to: - switch to using APIs that allowed the user to be specified. For example, using queryIntentServicesAsUse instead of getServiceInfo - don't look for work profiles if the calling user isn't the owner. The default connection manager (set using a config.xml overlay) didn't work with work profiles. Fix was to allow the default connection manager to resolve against the calling process's user handle. BUG: 19300886, 19301690, 19301359 Change-Id: I49d75b69dcfc829b74a5483d7a011f17d8d06838
Diffstat (limited to 'src/com')
-rw-r--r--src/com/android/server/telecom/CreateConnectionProcessor.java7
-rw-r--r--src/com/android/server/telecom/PhoneAccountRegistrar.java60
-rw-r--r--src/com/android/server/telecom/TelecomServiceImpl.java8
3 files changed, 53 insertions, 22 deletions
diff --git a/src/com/android/server/telecom/CreateConnectionProcessor.java b/src/com/android/server/telecom/CreateConnectionProcessor.java
index eec14277..31114dfd 100644
--- a/src/com/android/server/telecom/CreateConnectionProcessor.java
+++ b/src/com/android/server/telecom/CreateConnectionProcessor.java
@@ -267,6 +267,10 @@ final class CreateConnectionProcessor {
// Connection managers are only allowed to manage SIM subscriptions.
PhoneAccount targetPhoneAccount = mPhoneAccountRegistrar.getPhoneAccount(
targetPhoneAccountHandle);
+ if (targetPhoneAccount == null) {
+ Log.d(this, "shouldSetConnectionManager, phone account not found");
+ return false;
+ }
boolean isSimSubscription = (targetPhoneAccount.getCapabilities() &
PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION) != 0;
if (!isSimSubscription) {
@@ -326,7 +330,8 @@ final class CreateConnectionProcessor {
if (mShouldUseConnectionManager && callManagerHandle != null) {
PhoneAccount callManager = mPhoneAccountRegistrar
.getPhoneAccount(callManagerHandle);
- if (callManager.hasCapabilities(PhoneAccount.CAPABILITY_PLACE_EMERGENCY_CALLS)) {
+ if (callManager != null && callManager.hasCapabilities(
+ PhoneAccount.CAPABILITY_PLACE_EMERGENCY_CALLS)) {
CallAttemptRecord callAttemptRecord = new CallAttemptRecord(callManagerHandle,
mPhoneAccountRegistrar.
getDefaultOutgoingPhoneAccount(mCall.getHandle().getScheme())
diff --git a/src/com/android/server/telecom/PhoneAccountRegistrar.java b/src/com/android/server/telecom/PhoneAccountRegistrar.java
index bd6e2d2b..759a31dc 100644
--- a/src/com/android/server/telecom/PhoneAccountRegistrar.java
+++ b/src/com/android/server/telecom/PhoneAccountRegistrar.java
@@ -27,6 +27,7 @@ import android.content.pm.UserInfo;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
+import android.os.Binder;
import android.os.Process;
import android.os.UserHandle;
import android.os.UserManager;
@@ -65,6 +66,7 @@ import java.lang.Integer;
import java.lang.SecurityException;
import java.lang.String;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;
@@ -298,8 +300,16 @@ public final class PhoneAccountRegistrar {
mContext.getResources().getString(R.string.default_connection_manager_component);
if (!TextUtils.isEmpty(defaultConnectionMgr)) {
ComponentName componentName = ComponentName.unflattenFromString(defaultConnectionMgr);
+ if (componentName == null) {
+ return null;
+ }
+
// Make sure that the component can be resolved.
List<ResolveInfo> resolveInfos = resolveComponent(componentName, null);
+ if (resolveInfos.isEmpty()) {
+ resolveInfos = resolveComponent(componentName, Binder.getCallingUserHandle());
+ }
+
if (!resolveInfos.isEmpty()) {
// See if there is registered PhoneAccount by this component.
List<PhoneAccountHandle> handles = getAllPhoneAccountHandles();
@@ -381,16 +391,23 @@ public final class PhoneAccountRegistrar {
return true;
}
+ if (phoneAccountUserHandle.equals(Binder.getCallingUserHandle())) {
+ return true;
+ }
+
// Unlike in TelecomServiceImpl, we only care about *profiles* here. We want to make sure
// that we don't resolve PhoneAccount across *users*, but resolving across *profiles* is
// fine.
- List<UserInfo> profileUsers = mUserManager.getProfiles(mCurrentUserHandle.getIdentifier());
-
- for (UserInfo profileInfo : profileUsers) {
- if (profileInfo.getUserHandle().equals(phoneAccountUserHandle)) {
- return true;
+ if (UserHandle.getCallingUserId() == UserHandle.USER_OWNER) {
+ List<UserInfo> profileUsers =
+ mUserManager.getProfiles(mCurrentUserHandle.getIdentifier());
+ for (UserInfo profileInfo : profileUsers) {
+ if (profileInfo.getUserHandle().equals(phoneAccountUserHandle)) {
+ return true;
+ }
}
}
+
return false;
}
@@ -404,10 +421,15 @@ public final class PhoneAccountRegistrar {
PackageManager pm = mContext.getPackageManager();
Intent intent = new Intent(ConnectionService.SERVICE_INTERFACE);
intent.setComponent(componentName);
- if (userHandle != null) {
- return pm.queryIntentServicesAsUser(intent, 0, userHandle.getIdentifier());
- } else {
- return pm.queryIntentServices(intent, 0);
+ try {
+ if (userHandle != null) {
+ return pm.queryIntentServicesAsUser(intent, 0, userHandle.getIdentifier());
+ } else {
+ return pm.queryIntentServices(intent, 0);
+ }
+ } catch (SecurityException e) {
+ Log.v(this, "%s is not visible for the calling user", componentName);
+ return Collections.EMPTY_LIST;
}
}
@@ -614,17 +636,19 @@ public final class PhoneAccountRegistrar {
* @return {@code True} if the phone account has permission.
*/
public boolean phoneAccountHasPermission(PhoneAccountHandle phoneAccountHandle) {
- PackageManager packageManager = mContext.getPackageManager();
- try {
- ServiceInfo serviceInfo = packageManager.getServiceInfo(
- phoneAccountHandle.getComponentName(), 0);
-
- return serviceInfo.permission != null &&
- serviceInfo.permission.equals(Manifest.permission.BIND_CONNECTION_SERVICE);
- } catch (PackageManager.NameNotFoundException e) {
- Log.w(this, "Name not found %s", e);
+ List<ResolveInfo> resolveInfos = resolveComponent(phoneAccountHandle);
+ if (resolveInfos.isEmpty()) {
+ Log.w(this, "phoneAccount %s not found", phoneAccountHandle.getComponentName());
return false;
}
+ for (ResolveInfo resolveInfo : resolveInfos) {
+ ServiceInfo serviceInfo = resolveInfo.serviceInfo;
+ if (serviceInfo == null || !Objects.equals(serviceInfo.permission,
+ Manifest.permission.BIND_CONNECTION_SERVICE)) {
+ return false;
+ }
+ }
+ return true;
}
////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/com/android/server/telecom/TelecomServiceImpl.java b/src/com/android/server/telecom/TelecomServiceImpl.java
index e9df1a7a..c52c5251 100644
--- a/src/com/android/server/telecom/TelecomServiceImpl.java
+++ b/src/com/android/server/telecom/TelecomServiceImpl.java
@@ -747,10 +747,12 @@ public class TelecomServiceImpl {
return false;
}
+ if (phoneAccountUserHandle.equals(Binder.getCallingUserHandle())) {
+ return true;
+ }
+
List<UserHandle> profileUserHandles;
- if (isCallerSystemApp()) {
- // If the caller lives in /system/priv-app, it can see PhoneAccounts for all of the
- // *profiles* that the calling user owns, but not for any other *users*.
+ if (UserHandle.getCallingUserId() == UserHandle.USER_OWNER) {
profileUserHandles = mUserManager.getUserProfiles();
} else {
// Otherwise, it has to be owned by the current caller's profile.