Replace oneway shortcut api with AndroidFuture
Oneway calls to the system process can cause more trouble along those lines than they solve. Asynchronous incall pressure to the system process is worse than synchronous incall pressure: it causes catastrophic failure modes and is also much harder to diagnose when problems happen. It's also much harder to guarantee transactionality when the caller side is asynchronous. Bug: 184878227 Test: atest ShortcutManagerTest1 ShortcutManagerTest2 ShortcutManagerTest3 ShortcutManagerTest4 ShortcutManagerTest5 ShortcutManagerTest6 ShortcutManagerTest7 ShortcutManagerTest8 ShortcutManagerTest9 ShortcutManagerTest10 ShortcutManagerTest11 Test: atest CtsShortcutManagerTestCases Change-Id: I4ec6b188f079c018902bedf32198c04e9c45a60d Change-Id: I854de382ee6bdc5ae32b6874b7d875dfe6c03c40
This commit is contained in:
@@ -26,29 +26,29 @@ import com.android.internal.infra.AndroidFuture;
|
||||
/** {@hide} */
|
||||
interface IShortcutService {
|
||||
|
||||
oneway void setDynamicShortcuts(String packageName, in ParceledListSlice shortcutInfoList,
|
||||
int userId, in AndroidFuture callback);
|
||||
AndroidFuture setDynamicShortcuts(String packageName,
|
||||
in ParceledListSlice shortcutInfoList, int userId);
|
||||
|
||||
oneway void addDynamicShortcuts(String packageName, in ParceledListSlice shortcutInfoList,
|
||||
int userId, in AndroidFuture callback);
|
||||
AndroidFuture addDynamicShortcuts(String packageName,
|
||||
in ParceledListSlice shortcutInfoList, int userId);
|
||||
|
||||
oneway void removeDynamicShortcuts(String packageName, in List shortcutIds, int userId);
|
||||
AndroidFuture removeDynamicShortcuts(String packageName, in List shortcutIds, int userId);
|
||||
|
||||
oneway void removeAllDynamicShortcuts(String packageName, int userId);
|
||||
AndroidFuture removeAllDynamicShortcuts(String packageName, int userId);
|
||||
|
||||
oneway void updateShortcuts(String packageName, in ParceledListSlice shortcuts, int userId,
|
||||
in AndroidFuture callback);
|
||||
AndroidFuture updateShortcuts(String packageName, in ParceledListSlice shortcuts,
|
||||
int userId);
|
||||
|
||||
oneway void requestPinShortcut(String packageName, in ShortcutInfo shortcut,
|
||||
in IntentSender resultIntent, int userId, in AndroidFuture callback);
|
||||
AndroidFuture requestPinShortcut(String packageName, in ShortcutInfo shortcut,
|
||||
in IntentSender resultIntent, int userId);
|
||||
|
||||
oneway void createShortcutResultIntent(String packageName, in ShortcutInfo shortcut,
|
||||
int userId, in AndroidFuture callback);
|
||||
AndroidFuture<Intent> createShortcutResultIntent(String packageName, in ShortcutInfo shortcut,
|
||||
int userId);
|
||||
|
||||
oneway void disableShortcuts(String packageName, in List shortcutIds,
|
||||
AndroidFuture disableShortcuts(String packageName, in List shortcutIds,
|
||||
CharSequence disabledMessage, int disabledMessageResId, int userId);
|
||||
|
||||
oneway void enableShortcuts(String packageName, in List shortcutIds, int userId);
|
||||
AndroidFuture enableShortcuts(String packageName, in List shortcutIds, int userId);
|
||||
|
||||
int getMaxShortcutCountPerActivity(String packageName, int userId);
|
||||
|
||||
@@ -58,31 +58,30 @@ interface IShortcutService {
|
||||
|
||||
int getIconMaxDimensions(String packageName, int userId);
|
||||
|
||||
oneway void reportShortcutUsed(String packageName, String shortcutId, int userId);
|
||||
AndroidFuture reportShortcutUsed(String packageName, String shortcutId, int userId);
|
||||
|
||||
oneway void resetThrottling(); // system only API for developer opsions
|
||||
void resetThrottling(); // system only API for developer opsions
|
||||
|
||||
oneway void onApplicationActive(String packageName, int userId); // system only API for sysUI
|
||||
AndroidFuture onApplicationActive(String packageName, int userId); // system only API for sysUI
|
||||
|
||||
byte[] getBackupPayload(int user);
|
||||
|
||||
oneway void applyRestore(in byte[] payload, int user);
|
||||
AndroidFuture applyRestore(in byte[] payload, int user);
|
||||
|
||||
boolean isRequestPinItemSupported(int user, int requestType);
|
||||
|
||||
// System API used by framework's ShareSheet (ChooserActivity)
|
||||
oneway void getShareTargets(String packageName, in IntentFilter filter, int userId,
|
||||
in AndroidFuture<ParceledListSlice> callback);
|
||||
AndroidFuture<ParceledListSlice> getShareTargets(String packageName, in IntentFilter filter,
|
||||
int userId);
|
||||
|
||||
boolean hasShareTargets(String packageName, String packageToCheck, int userId);
|
||||
|
||||
oneway void removeLongLivedShortcuts(String packageName, in List shortcutIds, int userId);
|
||||
AndroidFuture removeLongLivedShortcuts(String packageName, in List shortcutIds, int userId);
|
||||
|
||||
oneway void getShortcuts(String packageName, int matchFlags, int userId,
|
||||
in AndroidFuture<ParceledListSlice<ShortcutInfo>> callback);
|
||||
AndroidFuture<ParceledListSlice> getShortcuts(String packageName, int matchFlags, int userId);
|
||||
|
||||
oneway void pushDynamicShortcut(String packageName, in ShortcutInfo shortcut, int userId);
|
||||
AndroidFuture pushDynamicShortcut(String packageName, in ShortcutInfo shortcut, int userId);
|
||||
|
||||
oneway void updateShortcutVisibility(String callingPkg, String packageName,
|
||||
AndroidFuture updateShortcutVisibility(String callingPkg, String packageName,
|
||||
in byte[] certificate, in boolean visible, int userId);
|
||||
}
|
||||
|
||||
@@ -145,14 +145,13 @@ public class ShortcutManager {
|
||||
*/
|
||||
@WorkerThread
|
||||
public boolean setDynamicShortcuts(@NonNull List<ShortcutInfo> shortcutInfoList) {
|
||||
final AndroidFuture<Boolean> future = new AndroidFuture<>();
|
||||
try {
|
||||
mService.setDynamicShortcuts(mContext.getPackageName(),
|
||||
new ParceledListSlice(shortcutInfoList), injectMyUserId(), future);
|
||||
return ((boolean) getFutureOrThrow(mService.setDynamicShortcuts(
|
||||
mContext.getPackageName(), new ParceledListSlice(
|
||||
shortcutInfoList), injectMyUserId())));
|
||||
} catch (RemoteException e) {
|
||||
future.completeExceptionally(e);
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
return getFutureOrThrow(future);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -167,14 +166,12 @@ public class ShortcutManager {
|
||||
@WorkerThread
|
||||
@NonNull
|
||||
public List<ShortcutInfo> getDynamicShortcuts() {
|
||||
final AndroidFuture<ParceledListSlice<ShortcutInfo>> future = new AndroidFuture<>();
|
||||
try {
|
||||
mService.getShortcuts(mContext.getPackageName(), FLAG_MATCH_DYNAMIC, injectMyUserId(),
|
||||
future);
|
||||
return getFutureOrThrow(mService.getShortcuts(mContext.getPackageName(),
|
||||
FLAG_MATCH_DYNAMIC, injectMyUserId())).getList();
|
||||
} catch (RemoteException e) {
|
||||
future.completeExceptionally(e);
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
return getFutureOrThrow(future).getList();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -189,14 +186,12 @@ public class ShortcutManager {
|
||||
@WorkerThread
|
||||
@NonNull
|
||||
public List<ShortcutInfo> getManifestShortcuts() {
|
||||
final AndroidFuture<ParceledListSlice<ShortcutInfo>> future = new AndroidFuture<>();
|
||||
try {
|
||||
mService.getShortcuts(mContext.getPackageName(), FLAG_MATCH_MANIFEST, injectMyUserId(),
|
||||
future);
|
||||
return getFutureOrThrow(mService.getShortcuts(mContext.getPackageName(),
|
||||
FLAG_MATCH_MANIFEST, injectMyUserId())).getList();
|
||||
} catch (RemoteException e) {
|
||||
future.completeExceptionally(e);
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
return getFutureOrThrow(future).getList();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -220,13 +215,12 @@ public class ShortcutManager {
|
||||
@WorkerThread
|
||||
@NonNull
|
||||
public List<ShortcutInfo> getShortcuts(@ShortcutMatchFlags int matchFlags) {
|
||||
final AndroidFuture<ParceledListSlice<ShortcutInfo>> future = new AndroidFuture<>();
|
||||
try {
|
||||
mService.getShortcuts(mContext.getPackageName(), matchFlags, injectMyUserId(), future);
|
||||
return getFutureOrThrow(mService.getShortcuts(mContext.getPackageName(), matchFlags,
|
||||
injectMyUserId())).getList();
|
||||
} catch (RemoteException e) {
|
||||
future.completeExceptionally(e);
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
return getFutureOrThrow(future).getList();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -244,14 +238,13 @@ public class ShortcutManager {
|
||||
*/
|
||||
@WorkerThread
|
||||
public boolean addDynamicShortcuts(@NonNull List<ShortcutInfo> shortcutInfoList) {
|
||||
final AndroidFuture<Boolean> future = new AndroidFuture<>();
|
||||
try {
|
||||
mService.addDynamicShortcuts(mContext.getPackageName(),
|
||||
new ParceledListSlice(shortcutInfoList), injectMyUserId(), future);
|
||||
return (boolean) getFutureOrThrow(mService.addDynamicShortcuts(
|
||||
mContext.getPackageName(), new ParceledListSlice(shortcutInfoList),
|
||||
injectMyUserId()));
|
||||
} catch (RemoteException e) {
|
||||
future.completeExceptionally(e);
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
return getFutureOrThrow(future);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -261,8 +254,8 @@ public class ShortcutManager {
|
||||
*/
|
||||
public void removeDynamicShortcuts(@NonNull List<String> shortcutIds) {
|
||||
try {
|
||||
mService.removeDynamicShortcuts(mContext.getPackageName(), shortcutIds,
|
||||
injectMyUserId());
|
||||
getFutureOrThrow(mService.removeDynamicShortcuts(mContext.getPackageName(), shortcutIds,
|
||||
injectMyUserId()));
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
@@ -275,7 +268,8 @@ public class ShortcutManager {
|
||||
*/
|
||||
public void removeAllDynamicShortcuts() {
|
||||
try {
|
||||
mService.removeAllDynamicShortcuts(mContext.getPackageName(), injectMyUserId());
|
||||
getFutureOrThrow(mService.removeAllDynamicShortcuts(mContext.getPackageName(),
|
||||
injectMyUserId()));
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
@@ -288,8 +282,8 @@ public class ShortcutManager {
|
||||
*/
|
||||
public void removeLongLivedShortcuts(@NonNull List<String> shortcutIds) {
|
||||
try {
|
||||
mService.removeLongLivedShortcuts(mContext.getPackageName(), shortcutIds,
|
||||
injectMyUserId());
|
||||
getFutureOrThrow(mService.removeLongLivedShortcuts(mContext.getPackageName(),
|
||||
shortcutIds, injectMyUserId()));
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
@@ -307,14 +301,12 @@ public class ShortcutManager {
|
||||
@WorkerThread
|
||||
@NonNull
|
||||
public List<ShortcutInfo> getPinnedShortcuts() {
|
||||
final AndroidFuture<ParceledListSlice<ShortcutInfo>> future = new AndroidFuture<>();
|
||||
try {
|
||||
mService.getShortcuts(mContext.getPackageName(), FLAG_MATCH_PINNED, injectMyUserId(),
|
||||
future);
|
||||
return getFutureOrThrow(mService.getShortcuts(mContext.getPackageName(),
|
||||
FLAG_MATCH_PINNED, injectMyUserId())).getList();
|
||||
} catch (RemoteException e) {
|
||||
future.completeExceptionally(e);
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
return getFutureOrThrow(future).getList();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -331,14 +323,12 @@ public class ShortcutManager {
|
||||
*/
|
||||
@WorkerThread
|
||||
public boolean updateShortcuts(@NonNull List<ShortcutInfo> shortcutInfoList) {
|
||||
final AndroidFuture<Boolean> future = new AndroidFuture<>();
|
||||
try {
|
||||
mService.updateShortcuts(mContext.getPackageName(),
|
||||
new ParceledListSlice(shortcutInfoList), injectMyUserId(), future);
|
||||
return (boolean) getFutureOrThrow(mService.updateShortcuts(mContext.getPackageName(),
|
||||
new ParceledListSlice(shortcutInfoList), injectMyUserId()));
|
||||
} catch (RemoteException e) {
|
||||
future.completeExceptionally(e);
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
return getFutureOrThrow(future);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -352,9 +342,9 @@ public class ShortcutManager {
|
||||
*/
|
||||
public void disableShortcuts(@NonNull List<String> shortcutIds) {
|
||||
try {
|
||||
mService.disableShortcuts(mContext.getPackageName(), shortcutIds,
|
||||
getFutureOrThrow(mService.disableShortcuts(mContext.getPackageName(), shortcutIds,
|
||||
/* disabledMessage =*/ null, /* disabledMessageResId =*/ 0,
|
||||
injectMyUserId());
|
||||
injectMyUserId()));
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
@@ -365,9 +355,9 @@ public class ShortcutManager {
|
||||
*/
|
||||
public void disableShortcuts(@NonNull List<String> shortcutIds, int disabledMessageResId) {
|
||||
try {
|
||||
mService.disableShortcuts(mContext.getPackageName(), shortcutIds,
|
||||
getFutureOrThrow(mService.disableShortcuts(mContext.getPackageName(), shortcutIds,
|
||||
/* disabledMessage =*/ null, disabledMessageResId,
|
||||
injectMyUserId());
|
||||
injectMyUserId()));
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
@@ -393,9 +383,9 @@ public class ShortcutManager {
|
||||
*/
|
||||
public void disableShortcuts(@NonNull List<String> shortcutIds, CharSequence disabledMessage) {
|
||||
try {
|
||||
mService.disableShortcuts(mContext.getPackageName(), shortcutIds,
|
||||
getFutureOrThrow(mService.disableShortcuts(mContext.getPackageName(), shortcutIds,
|
||||
disabledMessage, /* disabledMessageResId =*/ 0,
|
||||
injectMyUserId());
|
||||
injectMyUserId()));
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
@@ -411,7 +401,8 @@ public class ShortcutManager {
|
||||
*/
|
||||
public void enableShortcuts(@NonNull List<String> shortcutIds) {
|
||||
try {
|
||||
mService.enableShortcuts(mContext.getPackageName(), shortcutIds, injectMyUserId());
|
||||
getFutureOrThrow(mService.enableShortcuts(
|
||||
mContext.getPackageName(), shortcutIds, injectMyUserId()));
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
@@ -532,8 +523,8 @@ public class ShortcutManager {
|
||||
*/
|
||||
public void reportShortcutUsed(String shortcutId) {
|
||||
try {
|
||||
mService.reportShortcutUsed(mContext.getPackageName(), shortcutId,
|
||||
injectMyUserId());
|
||||
getFutureOrThrow(mService.reportShortcutUsed(mContext.getPackageName(), shortcutId,
|
||||
injectMyUserId()));
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
@@ -610,14 +601,12 @@ public class ShortcutManager {
|
||||
@WorkerThread
|
||||
public boolean requestPinShortcut(@NonNull ShortcutInfo shortcut,
|
||||
@Nullable IntentSender resultIntent) {
|
||||
final AndroidFuture<Boolean> future = new AndroidFuture<>();
|
||||
try {
|
||||
mService.requestPinShortcut(mContext.getPackageName(), shortcut,
|
||||
resultIntent, injectMyUserId(), future);
|
||||
return (boolean) getFutureOrThrow(mService.requestPinShortcut(mContext.getPackageName(),
|
||||
shortcut, resultIntent, injectMyUserId()));
|
||||
} catch (RemoteException e) {
|
||||
future.completeExceptionally(e);
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
return getFutureOrThrow(future);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -639,14 +628,12 @@ public class ShortcutManager {
|
||||
*/
|
||||
@WorkerThread
|
||||
public Intent createShortcutResultIntent(@NonNull ShortcutInfo shortcut) {
|
||||
final AndroidFuture<Intent> future = new AndroidFuture<>();
|
||||
try {
|
||||
mService.createShortcutResultIntent(mContext.getPackageName(), shortcut,
|
||||
injectMyUserId(), future);
|
||||
return getFutureOrThrow(mService.createShortcutResultIntent(mContext.getPackageName(),
|
||||
shortcut, injectMyUserId()));
|
||||
} catch (RemoteException e) {
|
||||
future.completeExceptionally(e);
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
return getFutureOrThrow(future);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -659,7 +646,7 @@ public class ShortcutManager {
|
||||
*/
|
||||
public void onApplicationActive(@NonNull String packageName, @UserIdInt int userId) {
|
||||
try {
|
||||
mService.onApplicationActive(packageName, userId);
|
||||
getFutureOrThrow(mService.onApplicationActive(packageName, userId));
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
@@ -684,13 +671,12 @@ public class ShortcutManager {
|
||||
@SystemApi
|
||||
@RequiresPermission(Manifest.permission.MANAGE_APP_PREDICTIONS)
|
||||
public List<ShareShortcutInfo> getShareTargets(@NonNull IntentFilter filter) {
|
||||
final AndroidFuture<ParceledListSlice> future = new AndroidFuture<>();
|
||||
try {
|
||||
mService.getShareTargets(mContext.getPackageName(), filter, injectMyUserId(), future);
|
||||
return getFutureOrThrow(mService.getShareTargets(mContext.getPackageName(), filter,
|
||||
injectMyUserId())).getList();
|
||||
} catch (RemoteException e) {
|
||||
future.completeExceptionally(e);
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
return getFutureOrThrow(future).getList();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -797,7 +783,8 @@ public class ShortcutManager {
|
||||
*/
|
||||
public void pushDynamicShortcut(@NonNull ShortcutInfo shortcut) {
|
||||
try {
|
||||
mService.pushDynamicShortcut(mContext.getPackageName(), shortcut, injectMyUserId());
|
||||
getFutureOrThrow(mService.pushDynamicShortcut(
|
||||
mContext.getPackageName(), shortcut, injectMyUserId()));
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
@@ -813,8 +800,8 @@ public class ShortcutManager {
|
||||
public void updateShortcutVisibility(@NonNull final String packageName,
|
||||
@Nullable final byte[] certificate, final boolean visible) {
|
||||
try {
|
||||
mService.updateShortcutVisibility(mContext.getPackageName(), packageName, certificate,
|
||||
visible, injectMyUserId());
|
||||
getFutureOrThrow(mService.updateShortcutVisibility(mContext.getPackageName(),
|
||||
packageName, certificate, visible, injectMyUserId()));
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
|
||||
@@ -158,6 +158,8 @@ class ShortcutPackage extends ShortcutPackageItem {
|
||||
private static final String KEY_BITMAPS = "bitmaps";
|
||||
private static final String KEY_BITMAP_BYTES = "bitmapBytes";
|
||||
|
||||
private final Object mLock = new Object();
|
||||
|
||||
/**
|
||||
* An temp in-memory copy of shortcuts for this package that was loaded from xml, keyed on IDs.
|
||||
*/
|
||||
@@ -168,6 +170,11 @@ class ShortcutPackage extends ShortcutPackageItem {
|
||||
*/
|
||||
private final ArrayList<ShareTargetInfo> mShareTargets = new ArrayList<>(0);
|
||||
|
||||
/**
|
||||
* All external packages that have gained access to the shortcuts from this package
|
||||
*/
|
||||
private final Map<String, PackageIdentifier> mPackageIdentifiers = new ArrayMap<>(0);
|
||||
|
||||
/**
|
||||
* # of times the package has called rate-limited APIs.
|
||||
*/
|
||||
@@ -182,13 +189,6 @@ class ShortcutPackage extends ShortcutPackageItem {
|
||||
|
||||
private long mLastKnownForegroundElapsedTime;
|
||||
|
||||
private final Object mLock = new Object();
|
||||
|
||||
/**
|
||||
* All external packages that have gained access to the shortcuts from this package
|
||||
*/
|
||||
private final Map<String, PackageIdentifier> mPackageIdentifiers = new ArrayMap<>(0);
|
||||
|
||||
private boolean mIsInitilized;
|
||||
|
||||
private ShortcutPackage(ShortcutUser shortcutUser,
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user