Search in sources :

Example 1 with IRemoteViewsFactory

use of com.android.internal.widget.IRemoteViewsFactory in project android_frameworks_base by ParanoidAndroid.

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);
        remoteViews.setUser(new UserHandle(mUserId));
        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) {
            ArrayList<Integer> 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() ");
        }
    }
}
Also used : UserHandle(android.os.UserHandle) IRemoteViewsFactory(com.android.internal.widget.IRemoteViewsFactory) RemoteException(android.os.RemoteException)

Example 2 with IRemoteViewsFactory

use of com.android.internal.widget.IRemoteViewsFactory in project android_frameworks_base by ParanoidAndroid.

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;
    ArrayList<Integer> 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;
}
Also used : IRemoteViewsFactory(com.android.internal.widget.IRemoteViewsFactory) RemoteException(android.os.RemoteException)

Example 3 with IRemoteViewsFactory

use of com.android.internal.widget.IRemoteViewsFactory in project platform_frameworks_base by android.

the class AppWidgetServiceImpl method handleNotifyAppWidgetViewDataChanged.

private void handleNotifyAppWidgetViewDataChanged(Host host, IAppWidgetHost callbacks, int appWidgetId, int viewId, long requestTime) {
    try {
        callbacks.viewDataChanged(appWidgetId, viewId);
        host.lastWidgetUpdateTime = requestTime;
    } catch (RemoteException re) {
        // It failed; remove the callback. No need to prune because
        // we know that this host is still referenced by this instance.
        callbacks = null;
    }
    // RemoteViewsFactory.onDataSetChanged() directly
    synchronized (mLock) {
        if (callbacks == null) {
            host.callbacks = null;
            Set<Pair<Integer, FilterComparison>> keys = mRemoteViewsServicesAppWidgets.keySet();
            for (Pair<Integer, FilterComparison> key : keys) {
                if (mRemoteViewsServicesAppWidgets.get(key).contains(appWidgetId)) {
                    final ServiceConnection connection = new ServiceConnection() {

                        @Override
                        public void onServiceConnected(ComponentName name, IBinder service) {
                            IRemoteViewsFactory cb = IRemoteViewsFactory.Stub.asInterface(service);
                            try {
                                cb.onDataSetChangedAsync();
                            } catch (RemoteException e) {
                                Slog.e(TAG, "Error calling onDataSetChangedAsync()", e);
                            }
                            mContext.unbindService(this);
                        }

                        @Override
                        public void onServiceDisconnected(android.content.ComponentName name) {
                        // Do nothing
                        }
                    };
                    final int userId = UserHandle.getUserId(key.first);
                    Intent intent = key.second.getIntent();
                    // Bind to the service and call onDataSetChanged()
                    bindService(intent, connection, new UserHandle(userId));
                }
            }
        }
    }
}
Also used : ServiceConnection(android.content.ServiceConnection) PendingIntent(android.app.PendingIntent) Intent(android.content.Intent) Point(android.graphics.Point) IBinder(android.os.IBinder) UserHandle(android.os.UserHandle) IRemoteViewsFactory(com.android.internal.widget.IRemoteViewsFactory) FilterComparison(android.content.Intent.FilterComparison) ComponentName(android.content.ComponentName) RemoteException(android.os.RemoteException) Pair(android.util.Pair)

Example 4 with IRemoteViewsFactory

use of com.android.internal.widget.IRemoteViewsFactory in project platform_frameworks_base by android.

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);
    }
}
Also used : ServiceConnection(android.content.ServiceConnection) IBinder(android.os.IBinder) IRemoteViewsFactory(com.android.internal.widget.IRemoteViewsFactory) ComponentName(android.content.ComponentName) RemoteException(android.os.RemoteException)

Example 5 with IRemoteViewsFactory

use of com.android.internal.widget.IRemoteViewsFactory in project platform_frameworks_base by android.

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;
}
Also used : IRemoteViewsFactory(com.android.internal.widget.IRemoteViewsFactory) RemoteException(android.os.RemoteException)

Aggregations

RemoteException (android.os.RemoteException)33 IRemoteViewsFactory (com.android.internal.widget.IRemoteViewsFactory)33 ComponentName (android.content.ComponentName)12 ServiceConnection (android.content.ServiceConnection)12 IBinder (android.os.IBinder)12 UserHandle (android.os.UserHandle)8 Point (android.graphics.Point)7 PendingIntent (android.app.PendingIntent)6 Intent (android.content.Intent)6 FilterComparison (android.content.Intent.FilterComparison)6 Pair (android.util.Pair)5