Loading core/java/android/appwidget/AppWidgetHost.java +20 −14 Original line number Diff line number Diff line Loading @@ -17,8 +17,7 @@ package android.appwidget; import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import android.annotation.NonNull; import android.annotation.Nullable; Loading @@ -35,7 +34,9 @@ import android.os.Message; import android.os.Process; import android.os.RemoteException; import android.os.ServiceManager; import android.os.SystemClock; import android.util.DisplayMetrics; import android.util.SparseArray; import android.util.TypedValue; import android.widget.RemoteViews; import android.widget.RemoteViews.OnClickHandler; Loading @@ -62,7 +63,7 @@ public class AppWidgetHost { private final Handler mHandler; private final int mHostId; private final Callbacks mCallbacks; private final HashMap<Integer,AppWidgetHostView> mViews = new HashMap<>(); private final SparseArray<AppWidgetHostView> mViews = new SparseArray<>(); private OnClickHandler mOnClickHandler; static class Callbacks extends IAppWidgetHost.Stub { Loading Loading @@ -164,7 +165,6 @@ public class AppWidgetHost { bindService(); } private static void bindService() { synchronized (sServiceLock) { if (sService == null) { Loading @@ -179,17 +179,25 @@ public class AppWidgetHost { * becomes visible, i.e. from onStart() in your Activity. */ public void startListening() { int[] updatedIds; ArrayList<RemoteViews> updatedViews = new ArrayList<RemoteViews>(); final int[] idsToUpdate; synchronized (mViews) { int N = mViews.size(); idsToUpdate = new int[N]; for (int i = 0; i < N; i++) { idsToUpdate[i] = mViews.keyAt(i); } } List<RemoteViews> updatedViews; int[] updatedIds = new int[idsToUpdate.length]; try { updatedIds = sService.startListening(mCallbacks, mContextOpPackageName, mHostId, updatedViews); updatedViews = sService.startListening( mCallbacks, mContextOpPackageName, mHostId, idsToUpdate, updatedIds).getList(); } catch (RemoteException e) { throw new RuntimeException("system server dead?", e); } final int N = updatedIds.length; int N = updatedViews.size(); for (int i = 0; i < N; i++) { updateAppWidgetView(updatedIds[i], updatedViews.get(i)); } Loading @@ -206,10 +214,6 @@ public class AppWidgetHost { catch (RemoteException e) { throw new RuntimeException("system server dead?", e); } // This is here because keyguard needs it since it'll be switching users after this call. // If it turns out other apps need to call this often, we should re-think how this works. clearViews(); } /** Loading Loading @@ -418,8 +422,10 @@ public class AppWidgetHost { * Clear the list of Views that have been created by this AppWidgetHost. */ protected void clearViews() { synchronized (mViews) { mViews.clear(); } } } core/java/com/android/internal/appwidget/IAppWidgetService.aidl +2 −2 Original line number Diff line number Diff line Loading @@ -33,8 +33,8 @@ interface IAppWidgetService { // // for AppWidgetHost // int[] startListening(IAppWidgetHost host, String callingPackage, int hostId, out List<RemoteViews> updatedViews); ParceledListSlice startListening(IAppWidgetHost host, String callingPackage, int hostId, in int[] appWidgetIds, out int[] updatedIds); void stopListening(String callingPackage, int hostId); int allocateAppWidgetId(String callingPackage, int hostId); void deleteAppWidgetId(String callingPackage, int appWidgetId); Loading services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java +41 −15 Original line number Diff line number Diff line Loading @@ -744,8 +744,8 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku } @Override public int[] startListening(IAppWidgetHost callbacks, String callingPackage, int hostId, List<RemoteViews> updatedViews) { public ParceledListSlice<RemoteViews> startListening(IAppWidgetHost callbacks, String callingPackage, int hostId, int[] appWidgetIds, int[] updatedIds) { final int userId = UserHandle.getCallingUserId(); if (DEBUG) { Loading @@ -762,21 +762,21 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku // sure the caller can only access hosts it owns. HostId id = new HostId(Binder.getCallingUid(), hostId, callingPackage); Host host = lookupOrAddHostLocked(id); host.callbacks = callbacks; updatedViews.clear(); ArrayList<Widget> instances = host.widgets; int N = instances.size(); int[] updatedIds = new int[N]; int N = appWidgetIds.length; ArrayList<RemoteViews> outViews = new ArrayList<>(N); RemoteViews rv; int added = 0; for (int i = 0; i < N; i++) { Widget widget = instances.get(i); updatedIds[i] = widget.appWidgetId; updatedViews.add(cloneIfLocalBinder(widget.getEffectiveViewsLocked())); rv = host.getPendingViewsForId(appWidgetIds[i]); if (rv != null) { updatedIds[added] = appWidgetIds[i]; outViews.add(rv); added++; } return updatedIds; } return new ParceledListSlice<>(outViews); } } Loading Loading @@ -1884,6 +1884,10 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku } private void scheduleNotifyUpdateAppWidgetLocked(Widget widget, RemoteViews updateViews) { long requestTime = SystemClock.uptimeMillis(); if (widget != null) { widget.lastUpdateTime = requestTime; } if (widget == null || widget.provider == null || widget.provider.zombie || widget.host.callbacks == null || widget.host.zombie) { return; Loading @@ -1893,6 +1897,7 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku args.arg1 = widget.host; args.arg2 = widget.host.callbacks; args.arg3 = updateViews; args.arg4 = requestTime; args.argi1 = widget.appWidgetId; mCallbackHandler.obtainMessage( Loading @@ -1901,9 +1906,10 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku } private void handleNotifyUpdateAppWidget(Host host, IAppWidgetHost callbacks, int appWidgetId, RemoteViews views) { int appWidgetId, RemoteViews views, long requestTime) { try { callbacks.updateAppWidget(appWidgetId, views); host.lastWidgetUpdateTime = requestTime; } catch (RemoteException re) { synchronized (mLock) { Slog.e(TAG, "Widget host dead: " + host.id, re); Loading Loading @@ -3400,10 +3406,11 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku Host host = (Host) args.arg1; IAppWidgetHost callbacks = (IAppWidgetHost) args.arg2; RemoteViews views = (RemoteViews) args.arg3; long requestTime = (Long) args.arg4; final int appWidgetId = args.argi1; args.recycle(); handleNotifyUpdateAppWidget(host, callbacks, appWidgetId, views); handleNotifyUpdateAppWidget(host, callbacks, appWidgetId, views, requestTime); } break; case MSG_NOTIFY_PROVIDER_CHANGED: { Loading Loading @@ -3771,6 +3778,7 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku boolean zombie; // if we're in safe mode, don't prune this just because nobody references it int tag = TAG_UNDEFINED; // for use while saving state (the index) long lastWidgetUpdateTime; // last time we were successfully able to send an update. public int getUserId() { return UserHandle.getUserId(id.uid); Loading @@ -3792,6 +3800,23 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku return false; } /** * Returns the RemoveViews for the provided widget id if an update is pending * for that widget. */ public RemoteViews getPendingViewsForId(int appWidgetId) { long updateTime = lastWidgetUpdateTime; int N = widgets.size(); for (int i = 0; i < N; i++) { Widget widget = widgets.get(i); if (widget.appWidgetId == appWidgetId && widget.lastUpdateTime > updateTime) { return cloneIfLocalBinder(widget.getEffectiveViewsLocked()); } } return null; } @Override public String toString() { return "Host{" + id + (zombie ? " Z" : "") + '}'; Loading Loading @@ -3862,6 +3887,7 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku RemoteViews maskedViews; Bundle options; Host host; long lastUpdateTime; @Override public String toString() { Loading Loading
core/java/android/appwidget/AppWidgetHost.java +20 −14 Original line number Diff line number Diff line Loading @@ -17,8 +17,7 @@ package android.appwidget; import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import android.annotation.NonNull; import android.annotation.Nullable; Loading @@ -35,7 +34,9 @@ import android.os.Message; import android.os.Process; import android.os.RemoteException; import android.os.ServiceManager; import android.os.SystemClock; import android.util.DisplayMetrics; import android.util.SparseArray; import android.util.TypedValue; import android.widget.RemoteViews; import android.widget.RemoteViews.OnClickHandler; Loading @@ -62,7 +63,7 @@ public class AppWidgetHost { private final Handler mHandler; private final int mHostId; private final Callbacks mCallbacks; private final HashMap<Integer,AppWidgetHostView> mViews = new HashMap<>(); private final SparseArray<AppWidgetHostView> mViews = new SparseArray<>(); private OnClickHandler mOnClickHandler; static class Callbacks extends IAppWidgetHost.Stub { Loading Loading @@ -164,7 +165,6 @@ public class AppWidgetHost { bindService(); } private static void bindService() { synchronized (sServiceLock) { if (sService == null) { Loading @@ -179,17 +179,25 @@ public class AppWidgetHost { * becomes visible, i.e. from onStart() in your Activity. */ public void startListening() { int[] updatedIds; ArrayList<RemoteViews> updatedViews = new ArrayList<RemoteViews>(); final int[] idsToUpdate; synchronized (mViews) { int N = mViews.size(); idsToUpdate = new int[N]; for (int i = 0; i < N; i++) { idsToUpdate[i] = mViews.keyAt(i); } } List<RemoteViews> updatedViews; int[] updatedIds = new int[idsToUpdate.length]; try { updatedIds = sService.startListening(mCallbacks, mContextOpPackageName, mHostId, updatedViews); updatedViews = sService.startListening( mCallbacks, mContextOpPackageName, mHostId, idsToUpdate, updatedIds).getList(); } catch (RemoteException e) { throw new RuntimeException("system server dead?", e); } final int N = updatedIds.length; int N = updatedViews.size(); for (int i = 0; i < N; i++) { updateAppWidgetView(updatedIds[i], updatedViews.get(i)); } Loading @@ -206,10 +214,6 @@ public class AppWidgetHost { catch (RemoteException e) { throw new RuntimeException("system server dead?", e); } // This is here because keyguard needs it since it'll be switching users after this call. // If it turns out other apps need to call this often, we should re-think how this works. clearViews(); } /** Loading Loading @@ -418,8 +422,10 @@ public class AppWidgetHost { * Clear the list of Views that have been created by this AppWidgetHost. */ protected void clearViews() { synchronized (mViews) { mViews.clear(); } } }
core/java/com/android/internal/appwidget/IAppWidgetService.aidl +2 −2 Original line number Diff line number Diff line Loading @@ -33,8 +33,8 @@ interface IAppWidgetService { // // for AppWidgetHost // int[] startListening(IAppWidgetHost host, String callingPackage, int hostId, out List<RemoteViews> updatedViews); ParceledListSlice startListening(IAppWidgetHost host, String callingPackage, int hostId, in int[] appWidgetIds, out int[] updatedIds); void stopListening(String callingPackage, int hostId); int allocateAppWidgetId(String callingPackage, int hostId); void deleteAppWidgetId(String callingPackage, int appWidgetId); Loading
services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java +41 −15 Original line number Diff line number Diff line Loading @@ -744,8 +744,8 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku } @Override public int[] startListening(IAppWidgetHost callbacks, String callingPackage, int hostId, List<RemoteViews> updatedViews) { public ParceledListSlice<RemoteViews> startListening(IAppWidgetHost callbacks, String callingPackage, int hostId, int[] appWidgetIds, int[] updatedIds) { final int userId = UserHandle.getCallingUserId(); if (DEBUG) { Loading @@ -762,21 +762,21 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku // sure the caller can only access hosts it owns. HostId id = new HostId(Binder.getCallingUid(), hostId, callingPackage); Host host = lookupOrAddHostLocked(id); host.callbacks = callbacks; updatedViews.clear(); ArrayList<Widget> instances = host.widgets; int N = instances.size(); int[] updatedIds = new int[N]; int N = appWidgetIds.length; ArrayList<RemoteViews> outViews = new ArrayList<>(N); RemoteViews rv; int added = 0; for (int i = 0; i < N; i++) { Widget widget = instances.get(i); updatedIds[i] = widget.appWidgetId; updatedViews.add(cloneIfLocalBinder(widget.getEffectiveViewsLocked())); rv = host.getPendingViewsForId(appWidgetIds[i]); if (rv != null) { updatedIds[added] = appWidgetIds[i]; outViews.add(rv); added++; } return updatedIds; } return new ParceledListSlice<>(outViews); } } Loading Loading @@ -1884,6 +1884,10 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku } private void scheduleNotifyUpdateAppWidgetLocked(Widget widget, RemoteViews updateViews) { long requestTime = SystemClock.uptimeMillis(); if (widget != null) { widget.lastUpdateTime = requestTime; } if (widget == null || widget.provider == null || widget.provider.zombie || widget.host.callbacks == null || widget.host.zombie) { return; Loading @@ -1893,6 +1897,7 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku args.arg1 = widget.host; args.arg2 = widget.host.callbacks; args.arg3 = updateViews; args.arg4 = requestTime; args.argi1 = widget.appWidgetId; mCallbackHandler.obtainMessage( Loading @@ -1901,9 +1906,10 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku } private void handleNotifyUpdateAppWidget(Host host, IAppWidgetHost callbacks, int appWidgetId, RemoteViews views) { int appWidgetId, RemoteViews views, long requestTime) { try { callbacks.updateAppWidget(appWidgetId, views); host.lastWidgetUpdateTime = requestTime; } catch (RemoteException re) { synchronized (mLock) { Slog.e(TAG, "Widget host dead: " + host.id, re); Loading Loading @@ -3400,10 +3406,11 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku Host host = (Host) args.arg1; IAppWidgetHost callbacks = (IAppWidgetHost) args.arg2; RemoteViews views = (RemoteViews) args.arg3; long requestTime = (Long) args.arg4; final int appWidgetId = args.argi1; args.recycle(); handleNotifyUpdateAppWidget(host, callbacks, appWidgetId, views); handleNotifyUpdateAppWidget(host, callbacks, appWidgetId, views, requestTime); } break; case MSG_NOTIFY_PROVIDER_CHANGED: { Loading Loading @@ -3771,6 +3778,7 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku boolean zombie; // if we're in safe mode, don't prune this just because nobody references it int tag = TAG_UNDEFINED; // for use while saving state (the index) long lastWidgetUpdateTime; // last time we were successfully able to send an update. public int getUserId() { return UserHandle.getUserId(id.uid); Loading @@ -3792,6 +3800,23 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku return false; } /** * Returns the RemoveViews for the provided widget id if an update is pending * for that widget. */ public RemoteViews getPendingViewsForId(int appWidgetId) { long updateTime = lastWidgetUpdateTime; int N = widgets.size(); for (int i = 0; i < N; i++) { Widget widget = widgets.get(i); if (widget.appWidgetId == appWidgetId && widget.lastUpdateTime > updateTime) { return cloneIfLocalBinder(widget.getEffectiveViewsLocked()); } } return null; } @Override public String toString() { return "Host{" + id + (zombie ? " Z" : "") + '}'; Loading Loading @@ -3862,6 +3887,7 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku RemoteViews maskedViews; Bundle options; Host host; long lastUpdateTime; @Override public String toString() { Loading