Merge "Changing startListening to only fetch views which are bound" into nyc-dev
This commit is contained in:
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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 {
|
||||
@@ -164,7 +165,6 @@ public class AppWidgetHost {
|
||||
bindService();
|
||||
}
|
||||
|
||||
|
||||
private static void bindService() {
|
||||
synchronized (sServiceLock) {
|
||||
if (sService == null) {
|
||||
@@ -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));
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -418,7 +422,9 @@ public class AppWidgetHost {
|
||||
* Clear the list of Views that have been created by this AppWidgetHost.
|
||||
*/
|
||||
protected void clearViews() {
|
||||
mViews.clear();
|
||||
synchronized (mViews) {
|
||||
mViews.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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) {
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
@@ -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(
|
||||
@@ -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);
|
||||
@@ -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: {
|
||||
@@ -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);
|
||||
@@ -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" : "") + '}';
|
||||
@@ -3862,6 +3887,7 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
|
||||
RemoteViews maskedViews;
|
||||
Bundle options;
|
||||
Host host;
|
||||
long lastUpdateTime;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
|
||||
Reference in New Issue
Block a user