/**
   * Process a set of {@link RemoteViews} coming in as an update from the AppWidget provider. Will
   * animate into these new views as needed
   */
  public void updateAppWidget(RemoteViews remoteViews) {

    if (LOGD) Log.d(TAG, "updateAppWidget called mOld=" + mOld);

    boolean recycled = false;
    View content = null;
    Exception exception = null;

    // Capture the old view into a bitmap so we can do the crossfade.
    if (CROSSFADE) {
      if (mFadeStartTime < 0) {
        if (mView != null) {
          final int width = mView.getWidth();
          final int height = mView.getHeight();
          try {
            mOld = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
          } catch (OutOfMemoryError e) {
            // we just won't do the fade
            mOld = null;
          }
          if (mOld != null) {
            // mView.drawIntoBitmap(mOld);
          }
        }
      }
    }

    if (remoteViews == null) {
      if (mViewMode == VIEW_MODE_DEFAULT) {
        // We've already done this -- nothing to do.
        return;
      }
      content = getDefaultView();
      mLayoutId = -1;
      mViewMode = VIEW_MODE_DEFAULT;
    } else {
      // Prepare a local reference to the remote Context so we're ready to
      // inflate any requested LayoutParams.
      mRemoteContext = getRemoteContext(remoteViews);
      int layoutId = remoteViews.getLayoutId();

      // If our stale view has been prepared to match active, and the new
      // layout matches, try recycling it
      if (content == null && layoutId == mLayoutId) {
        try {
          /// M: add for using customer view, migrated from GB to ICS to JB
          remoteViews.setHasUsedCustomerView(mInfo.hasUsedCustomerView);
          remoteViews.reapply(mContext, mView, mOnClickHandler);
          content = mView;
          recycled = true;
          if (LOGD) Log.d(TAG, "was able to recycled existing layout");
        } catch (RuntimeException e) {
          exception = e;
        }
      }

      // Try normal RemoteView inflation
      if (content == null) {
        try {
          /// M: add for using customer view, migrated from GB to ICS to JB
          remoteViews.setHasUsedCustomerView(mInfo.hasUsedCustomerView);
          content = remoteViews.apply(mContext, this, mOnClickHandler);
          if (LOGD) Log.d(TAG, "had to inflate new layout");
        } catch (RuntimeException e) {
          exception = e;
        }
      }

      mLayoutId = layoutId;
      mViewMode = VIEW_MODE_CONTENT;
    }

    if (content == null) {
      if (mViewMode == VIEW_MODE_ERROR) {
        // We've already done this -- nothing to do.
        return;
      }
      Log.w(TAG, "updateAppWidget couldn't find any view, using error view", exception);
      content = getErrorView();
      mViewMode = VIEW_MODE_ERROR;
    }

    if (!recycled) {
      prepareView(content);
      addView(content);
    }

    if (mView != content) {
      removeView(mView);
      mView = content;
    }

    if (CROSSFADE) {
      if (mFadeStartTime < 0) {
        // if there is already an animation in progress, don't do anything --
        // the new view will pop in on top of the old one during the cross fade,
        // and that looks okay.
        mFadeStartTime = SystemClock.uptimeMillis();
        invalidate();
      }
    }
  }