Migrate dialer to RoleManager

Test: ensure settings UI is ok, ensure stock dialer can still make a call
Change-Id: Iab835939fbb92af06d9440910fbde2725ca66f70
This commit is contained in:
Eugene Susla
2019-01-11 13:31:20 -08:00
parent 2bfd202ec5
commit 92b88c7fab
6 changed files with 75 additions and 53 deletions

View File

@@ -19,6 +19,8 @@ package android.app.role;
import android.annotation.SystemApi;
import android.annotation.TestApi;
import java.util.concurrent.CompletableFuture;
/**
* Callback for a {@link RoleManager} request.
*
@@ -37,4 +39,18 @@ public interface RoleManagerCallback {
* Signals a failure.
*/
void onFailure();
/** @hide */
class Future extends CompletableFuture<Void> implements RoleManagerCallback {
@Override
public void onSuccess() {
complete(null);
}
@Override
public void onFailure() {
completeExceptionally(new RuntimeException());
}
}
}

View File

@@ -22,6 +22,8 @@ import android.content.ComponentName;
import android.content.Context;
import android.os.Debug;
import android.provider.Settings;
import android.telecom.TelecomManager;
import android.text.TextUtils;
import android.util.Log;
import android.util.Slog;
@@ -102,6 +104,15 @@ public class LegacyRoleResolutionPolicy implements RoleManagerService.RoleHolder
ComponentName.unflattenFromString(legacyAssistant).getPackageName());
}
}
case RoleManager.ROLE_DIALER: {
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());
}
default: {
Slog.e(LOG_TAG, "Don't know how to find legacy role holders for " + roleName);
return Collections.emptyList();

View File

@@ -32,12 +32,14 @@ import android.os.RemoteException;
import android.os.UserHandle;
import android.rolecontrollerservice.IRoleControllerService;
import android.rolecontrollerservice.RoleControllerService;
import android.util.Log;
import android.util.Slog;
import com.android.internal.util.function.pooled.PooledLambda;
import com.android.server.FgThread;
import java.util.ArrayDeque;
import java.util.Arrays;
import java.util.Queue;
/**
@@ -226,10 +228,21 @@ public class RemoteRoleControllerService {
private boolean mCallbackNotified;
@Nullable
private final String mDebugName;
private Call(@NonNull CallExecutor callExecutor,
@NonNull IRoleManagerCallback callback) {
mCallExecutor = callExecutor;
mCallback = callback;
mDebugName = DEBUG
? Arrays.stream(Thread.currentThread().getStackTrace())
.filter(s -> s.getClassName().equals(
RemoteRoleControllerService.class.getName()))
.findFirst()
.get()
.getMethodName()
: null;
}
@WorkerThread
@@ -254,6 +267,10 @@ public class RemoteRoleControllerService {
@WorkerThread
private void notifyCallback(boolean success) {
if (DEBUG) {
Log.i(LOG_TAG, "notifyCallback(" + this
+ ", success = " + success + ")");
}
if (mCallbackNotified) {
return;
}
@@ -273,7 +290,7 @@ public class RemoteRoleControllerService {
@Override
public String toString() {
return "Call with callback: " + mCallback;
return DEBUG ? mDebugName : "Call with callback: " + mCallback;
}
@FunctionalInterface

View File

@@ -199,6 +199,7 @@ public class RoleManagerService extends SystemService implements RoleUserState.C
// for a given role before adding a migration statement for it here
migrateRoleIfNecessary(RoleManager.ROLE_SMS, userId);
migrateRoleIfNecessary(RoleManager.ROLE_ASSISTANT, userId);
migrateRoleIfNecessary(RoleManager.ROLE_DIALER, userId);
// Some vital packages state has changed since last role grant
// Run grants again

View File

@@ -15,17 +15,22 @@
package android.telecom;
import android.app.ActivityManager;
import android.app.role.RoleManager;
import android.app.role.RoleManagerCallback;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Binder;
import android.os.Process;
import android.os.UserHandle;
import android.provider.Settings;
import android.text.TextUtils;
import com.android.internal.util.CollectionUtils;
import java.util.ArrayList;
import java.util.List;
@@ -64,25 +69,24 @@ public class DefaultDialerManager {
* */
public static boolean setDefaultDialerApplication(Context context, String packageName,
int user) {
// Get old package name
String oldPackageName = Settings.Secure.getStringForUser(context.getContentResolver(),
Settings.Secure.DIALER_DEFAULT_APPLICATION, user);
long identity = Binder.clearCallingIdentity();
try {
context.getSystemService(RoleManager.class).addRoleHolderAsUser(
RoleManager.ROLE_DIALER, packageName, UserHandle.of(user),
AsyncTask.THREAD_POOL_EXECUTOR, new RoleManagerCallback() {
@Override
public void onSuccess() {}
if (packageName != null && oldPackageName != null && packageName.equals(oldPackageName)) {
// No change
return false;
}
// Only make the change if the new package belongs to a valid phone application
List<String> packageNames = getInstalledDialerApplications(context, user);
if (packageNames.contains(packageName)) {
// Update the secure setting.
Settings.Secure.putStringForUser(context.getContentResolver(),
Settings.Secure.DIALER_DEFAULT_APPLICATION, packageName, user);
@Override
public void onFailure() {
Log.w(TAG, "Failed to set default dialer to %s for user %s",
packageName, user);
}
});
return true;
} finally {
Binder.restoreCallingIdentity(identity);
}
return false;
}
/**
@@ -116,28 +120,12 @@ public class DefaultDialerManager {
* @hide
* */
public static String getDefaultDialerApplication(Context context, int user) {
String defaultPackageName = Settings.Secure.getStringForUser(context.getContentResolver(),
Settings.Secure.DIALER_DEFAULT_APPLICATION, user);
final List<String> packageNames = getInstalledDialerApplications(context, user);
// Verify that the default dialer has not been disabled or uninstalled.
if (packageNames.contains(defaultPackageName)) {
return defaultPackageName;
}
// No user-set dialer found, fallback to system dialer
String systemDialerPackageName = getTelecomManager(context).getSystemDialerPackage();
if (TextUtils.isEmpty(systemDialerPackageName)) {
// No system dialer configured at build time
return null;
}
if (packageNames.contains(systemDialerPackageName)) {
return systemDialerPackageName;
} else {
return null;
long identity = Binder.clearCallingIdentity();
try {
return CollectionUtils.firstOrNull(context.getSystemService(RoleManager.class)
.getRoleHoldersAsUser(RoleManager.ROLE_DIALER, UserHandle.of(user)));
} finally {
Binder.restoreCallingIdentity(identity);
}
}

View File

@@ -51,7 +51,6 @@ import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
@@ -635,20 +634,10 @@ public final class SmsApplication {
}
// Update the setting.
CompletableFuture<Void> res = new CompletableFuture<>();
RoleManagerCallback.Future res = new RoleManagerCallback.Future();
context.getSystemService(RoleManager.class).addRoleHolderAsUser(
RoleManager.ROLE_SMS, applicationData.mPackageName, UserHandle.of(userId),
AsyncTask.THREAD_POOL_EXECUTOR, new RoleManagerCallback() {
@Override
public void onSuccess() {
res.complete(null);
}
@Override
public void onFailure() {
res.completeExceptionally(new RuntimeException());
}
});
AsyncTask.THREAD_POOL_EXECUTOR, res);
try {
res.get(5, TimeUnit.SECONDS);
} catch (InterruptedException | ExecutionException | TimeoutException e) {