use of com.android.internal.widget.IRemoteViewsFactory in project android_frameworks_base by crdroidandroid.
the class AppWidgetServiceImpl method destroyRemoteViewsService.
// Destroys the cached factory on the RemoteViewsService's side related to the specified intent
private void destroyRemoteViewsService(final Intent intent, Widget widget) {
final ServiceConnection conn = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
final IRemoteViewsFactory cb = IRemoteViewsFactory.Stub.asInterface(service);
try {
cb.onDestroy(intent);
} catch (RemoteException re) {
Slog.e(TAG, "Error calling remove view factory", re);
}
mContext.unbindService(this);
}
@Override
public void onServiceDisconnected(ComponentName name) {
// Do nothing
}
};
// Bind to the service and remove the static intent->factory mapping in the
// RemoteViewsService.
final long token = Binder.clearCallingIdentity();
try {
mContext.bindServiceAsUser(intent, conn, Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE, widget.provider.info.getProfile());
} finally {
Binder.restoreCallingIdentity(token);
}
}
use of com.android.internal.widget.IRemoteViewsFactory in project android_frameworks_base by crdroidandroid.
the class RemoteViewsAdapter method onNotifyDataSetChanged.
private void onNotifyDataSetChanged() {
// Complete the actual notifyDataSetChanged() call initiated earlier
IRemoteViewsFactory factory = mServiceConnection.getRemoteViewsFactory();
try {
factory.onDataSetChanged();
} catch (RemoteException e) {
Log.e(TAG, "Error in updateNotifyDataSetChanged(): " + e.getMessage());
// changed)
return;
} catch (RuntimeException e) {
Log.e(TAG, "Error in updateNotifyDataSetChanged(): " + e.getMessage());
return;
}
// Flush the cache so that we can reload new items from the service
synchronized (mCache) {
mCache.reset();
}
// Re-request the new metadata (only after the notification to the factory)
updateTemporaryMetaData();
int newCount;
int[] visibleWindow;
synchronized (mCache.getTemporaryMetaData()) {
newCount = mCache.getTemporaryMetaData().count;
visibleWindow = getVisibleWindow(mVisibleWindowLowerBound, mVisibleWindowUpperBound, newCount);
}
// its data has changed.
for (int i : visibleWindow) {
// mWorkerThread), it is safe to assume that count is a valid representation.
if (i < newCount) {
updateRemoteViews(i, false);
}
}
// Propagate the notification back to the base adapter
mMainQueue.post(new Runnable() {
@Override
public void run() {
synchronized (mCache) {
mCache.commitTemporaryMetaData();
}
superNotifyDataSetChanged();
enqueueDeferredUnbindServiceMessage();
}
});
// Reset the notify flagflag
mNotifyDataSetChangedAfterOnServiceConnected = false;
}
use of com.android.internal.widget.IRemoteViewsFactory in project android_frameworks_base by crdroidandroid.
the class RemoteViewsAdapter method updateRemoteViews.
private void updateRemoteViews(final int position, boolean notifyWhenLoaded) {
IRemoteViewsFactory factory = mServiceConnection.getRemoteViewsFactory();
// Load the item information from the remote service
RemoteViews remoteViews = null;
long itemId = 0;
try {
remoteViews = factory.getViewAt(position);
itemId = factory.getItemId(position);
} catch (RemoteException e) {
Log.e(TAG, "Error in updateRemoteViews(" + position + "): " + e.getMessage());
// swapping from the loading view
return;
} catch (RuntimeException e) {
Log.e(TAG, "Error in updateRemoteViews(" + position + "): " + e.getMessage());
return;
}
if (remoteViews == null) {
// If a null view was returned, we break early to prevent it from getting
// into our cache and causing problems later. The effect is that the child at this
// position will remain as a loading view until it is updated.
Log.e(TAG, "Error in updateRemoteViews(" + position + "): " + " null RemoteViews " + "returned from RemoteViewsFactory.");
return;
}
int layoutId = remoteViews.getLayoutId();
RemoteViewsMetaData metaData = mCache.getMetaData();
boolean viewTypeInRange;
int cacheCount;
synchronized (metaData) {
viewTypeInRange = metaData.isViewTypeInRange(layoutId);
cacheCount = mCache.mMetaData.count;
}
synchronized (mCache) {
if (viewTypeInRange) {
int[] visibleWindow = getVisibleWindow(mVisibleWindowLowerBound, mVisibleWindowUpperBound, cacheCount);
// Cache the RemoteViews we loaded
mCache.insert(position, remoteViews, itemId, visibleWindow);
// Notify all the views that we have previously returned for this index that
// there is new data for it.
final RemoteViews rv = remoteViews;
if (notifyWhenLoaded) {
mMainQueue.post(new Runnable() {
@Override
public void run() {
mRequestedViews.notifyOnRemoteViewsLoaded(position, rv);
}
});
}
} else {
// We need to log an error here, as the the view type count specified by the
// factory is less than the number of view types returned. We don't return this
// view to the AdapterView, as this will cause an exception in the hosting process,
// which contains the associated AdapterView.
Log.e(TAG, "Error: widget's RemoteViewsFactory returns more view types than " + " indicated by getViewTypeCount() ");
}
}
}
Aggregations