From 3abd5488cca5b06c97251db453a5a6ed61e33ce8 Mon Sep 17 00:00:00 2001 From: Hyunyoung Song Date: Mon, 8 Jun 2015 18:41:04 -0700 Subject: Catch TransactionTooLargeException when loading widget provider list b/19904873 Change-Id: Ic0d13ee7513731706bc0f9fde8502acba0899cb3 Note: fix for almonte will be separate due to diff btw the branches.. --- src/com/android/launcher3/LauncherModel.java | 63 +++++++++++++++++++--------- 1 file changed, 44 insertions(+), 19 deletions(-) (limited to 'src') diff --git a/src/com/android/launcher3/LauncherModel.java b/src/com/android/launcher3/LauncherModel.java index 10b8648de..a132e919a 100644 --- a/src/com/android/launcher3/LauncherModel.java +++ b/src/com/android/launcher3/LauncherModel.java @@ -45,6 +45,7 @@ import android.os.Parcelable; import android.os.Process; import android.os.RemoteException; import android.os.SystemClock; +import android.os.TransactionTooLargeException; import android.provider.BaseColumns; import android.text.TextUtils; import android.util.Log; @@ -3284,27 +3285,51 @@ public class LauncherModel extends BroadcastReceiver public static List getWidgetProviders(Context context, boolean refresh) { - synchronized (sBgLock) { - if (sBgWidgetProviders == null || refresh) { - sBgWidgetProviders = new HashMap<>(); - AppWidgetManagerCompat wm = AppWidgetManagerCompat.getInstance(context); - LauncherAppWidgetProviderInfo info; - - List widgets = wm.getAllProviders(); - for (AppWidgetProviderInfo pInfo : widgets) { - info = LauncherAppWidgetProviderInfo.fromProviderInfo(context, pInfo); - UserHandleCompat user = wm.getUser(info); - sBgWidgetProviders.put(new ComponentKey(info.provider, user), info); - } - - Collection customWidgets = Launcher.getCustomAppWidgets().values(); - for (CustomAppWidget widget : customWidgets) { - info = new LauncherAppWidgetProviderInfo(context, widget); - UserHandleCompat user = wm.getUser(info); - sBgWidgetProviders.put(new ComponentKey(info.provider, user), info); + ArrayList results = + new ArrayList(); + try { + synchronized (sBgLock) { + if (sBgWidgetProviders == null || refresh) { + HashMap tmpWidgetProviders + = new HashMap<>(); + AppWidgetManagerCompat wm = AppWidgetManagerCompat.getInstance(context); + LauncherAppWidgetProviderInfo info; + + List widgets = wm.getAllProviders(); + for (AppWidgetProviderInfo pInfo : widgets) { + info = LauncherAppWidgetProviderInfo.fromProviderInfo(context, pInfo); + UserHandleCompat user = wm.getUser(info); + tmpWidgetProviders.put(new ComponentKey(info.provider, user), info); + } + + Collection customWidgets = Launcher.getCustomAppWidgets().values(); + for (CustomAppWidget widget : customWidgets) { + info = new LauncherAppWidgetProviderInfo(context, widget); + UserHandleCompat user = wm.getUser(info); + tmpWidgetProviders.put(new ComponentKey(info.provider, user), info); + } + // Replace the global list at the very end, so that if there is an exception, + // previously loaded provider list is used. + sBgWidgetProviders = tmpWidgetProviders; + } + results.addAll(sBgWidgetProviders.values()); + return results; + } + } catch (Exception e) { + if (e.getCause() instanceof TransactionTooLargeException) { + // the returned value may be incomplete and will not be refreshed until the next + // time Launcher starts. + // TODO: after figuring out a repro step, introduce a dirty bit to check when + // onResume is called to refresh the widget provider list. + synchronized (sBgLock) { + if (sBgWidgetProviders != null) { + results.addAll(sBgWidgetProviders.values()); + } + return results; } + } else { + throw e; } - return new ArrayList(sBgWidgetProviders.values()); } } -- cgit v1.2.3