Fix legacy role holder resolution for assistant, dialer and SMS.

The legacy settings for them can actually remain null and it was
handled specially to use the system default instead. If the legacy
role holders aren't resolved correctly, role implementation will do a
fallback grant which overrides permission state, whereas if they are
resolved correctly the normal fix up won't do an override.

Fixes: 139752137
Test: manual
Change-Id: I5cc301c3b7b459bdfaece0117bcacd984d1cb78f
This commit is contained in:
Hai Zhang
2019-08-21 16:35:18 -07:00
parent 65371b27c8
commit dbffb693a5
2 changed files with 49 additions and 46 deletions

View File

@@ -24,20 +24,17 @@ import android.content.Context;
import android.content.pm.PackageManager;
import android.content.pm.PackageManagerInternal;
import android.content.pm.ResolveInfo;
import android.os.Debug;
import android.provider.Settings;
import android.telecom.TelecomManager;
import android.text.TextUtils;
import android.util.Log;
import android.util.Slog;
import com.android.internal.R;
import com.android.internal.telephony.SmsApplication;
import com.android.internal.util.CollectionUtils;
import com.android.server.LocalServices;
import com.android.server.role.RoleManagerService;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
@@ -67,14 +64,25 @@ public class LegacyRoleResolutionPolicy implements RoleManagerService.RoleHolder
public List<String> getRoleHolders(@NonNull String roleName, @UserIdInt int userId) {
switch (roleName) {
case RoleManager.ROLE_ASSISTANT: {
String legacyAssistant = Settings.Secure.getStringForUser(
mContext.getContentResolver(), Settings.Secure.ASSISTANT, userId);
if (legacyAssistant == null || legacyAssistant.isEmpty()) {
return Collections.emptyList();
String packageName;
String setting = Settings.Secure.getStringForUser(mContext.getContentResolver(),
Settings.Secure.ASSISTANT, userId);
// AssistUtils was using the default assistant app if Settings.Secure.ASSISTANT is
// null, while only an empty string means user selected "None".
if (setting != null) {
if (!setting.isEmpty()) {
ComponentName componentName = ComponentName.unflattenFromString(setting);
packageName = componentName != null ? componentName.getPackageName() : null;
} else {
packageName = null;
}
} else if (mContext.getPackageManager().isDeviceUpgrading()) {
String defaultAssistant = mContext.getString(R.string.config_defaultAssistant);
packageName = !TextUtils.isEmpty(defaultAssistant) ? defaultAssistant : null;
} else {
return Collections.singletonList(
ComponentName.unflattenFromString(legacyAssistant).getPackageName());
packageName = null;
}
return CollectionUtils.singletonOrEmpty(packageName);
}
case RoleManager.ROLE_BROWSER: {
PackageManagerInternal packageManagerInternal = LocalServices.getService(
@@ -84,44 +92,36 @@ public class LegacyRoleResolutionPolicy implements RoleManagerService.RoleHolder
return CollectionUtils.singletonOrEmpty(packageName);
}
case RoleManager.ROLE_DIALER: {
String setting = Settings.Secure.getStringForUser(
mContext.getContentResolver(),
String setting = Settings.Secure.getStringForUser(mContext.getContentResolver(),
Settings.Secure.DIALER_DEFAULT_APPLICATION, userId);
return CollectionUtils.singletonOrEmpty(!TextUtils.isEmpty(setting)
? setting
: mContext.getSystemService(TelecomManager.class).getSystemDialerPackage());
String packageName;
if (!TextUtils.isEmpty(setting)) {
packageName = setting;
} else if (mContext.getPackageManager().isDeviceUpgrading()) {
// DefaultDialerManager was using the default dialer app if
// Settings.Secure.DIALER_DEFAULT_APPLICATION is invalid.
// TelecomManager.getSystemDialerPackage() won't work because it might not
// be ready.
packageName = mContext.getString(R.string.config_defaultDialer);
} else {
packageName = null;
}
return CollectionUtils.singletonOrEmpty(packageName);
}
case RoleManager.ROLE_SMS: {
// Moved over from SmsApplication#getApplication
String result = Settings.Secure.getStringForUser(
mContext.getContentResolver(),
String setting = Settings.Secure.getStringForUser(mContext.getContentResolver(),
Settings.Secure.SMS_DEFAULT_APPLICATION, userId);
// TODO: STOPSHIP: Remove the following code once we read the value of
// config_defaultSms in RoleControllerService.
if (result == null) {
Collection<SmsApplication.SmsApplicationData> applications =
SmsApplication.getApplicationCollectionAsUser(mContext, userId);
SmsApplication.SmsApplicationData applicationData;
String defaultPackage = mContext.getResources()
.getString(com.android.internal.R.string.default_sms_application);
applicationData =
SmsApplication.getApplicationForPackage(applications, defaultPackage);
if (applicationData == null) {
// Are there any applications?
if (applications.size() != 0) {
applicationData =
(SmsApplication.SmsApplicationData) applications.toArray()[0];
}
}
if (DEBUG) {
Log.i(LOG_TAG, "Found default sms app: " + applicationData
+ " among: " + applications + " from " + Debug.getCallers(4));
}
SmsApplication.SmsApplicationData app = applicationData;
result = app == null ? null : app.mPackageName;
String packageName;
if (!TextUtils.isEmpty(setting)) {
packageName = setting;
} else if (mContext.getPackageManager().isDeviceUpgrading()) {
// SmsApplication was using the default SMS app if
// Settings.Secure.DIALER_DEFAULT_APPLICATION is invalid.
packageName = mContext.getString(R.string.config_defaultSms);
} else {
packageName = null;
}
return CollectionUtils.singletonOrEmpty(result);
return CollectionUtils.singletonOrEmpty(packageName);
}
case RoleManager.ROLE_HOME: {
PackageManager packageManager = mContext.getPackageManager();

View File

@@ -1281,9 +1281,12 @@ public class VoiceInteractionManagerService extends SystemService {
RoleObserver(@NonNull @CallbackExecutor Executor executor) {
mRm.addOnRoleHoldersChangedListenerAsUser(executor, this, UserHandle.ALL);
UserHandle currentUser = UserHandle.of(LocalServices.getService(
ActivityManagerInternal.class).getCurrentUserId());
onRoleHoldersChanged(RoleManager.ROLE_ASSISTANT, currentUser);
// Sync only if assistant role has been initialized.
if (mRm.isRoleAvailable(RoleManager.ROLE_ASSISTANT)) {
UserHandle currentUser = UserHandle.of(LocalServices.getService(
ActivityManagerInternal.class).getCurrentUserId());
onRoleHoldersChanged(RoleManager.ROLE_ASSISTANT, currentUser);
}
}
private @NonNull String getDefaultRecognizer(@NonNull UserHandle user) {