content: package com.lody.virtual.server.notification;
  
  import android.content.Context;
  import android.content.pm.PackageManager;
  import android.graphics.Bitmap;
  import android.os.Build;
  import android.view.Gravity;
  import android.view.LayoutInflater;
  import android.view.View;
  import android.view.ViewGroup;
  import android.view.inputmethod.EditorInfo;
  import android.widget.FrameLayout;
  import android.widget.RemoteViews;
  import android.widget.TextView;
  
  import com.lody.virtual.R;
  import com.lody.virtual.helper.utils.Reflect;
  import com.lody.virtual.helper.utils.VLog;
  
  import java.util.ArrayList;
  import java.util.HashMap;
  
  
  /* package */ class RemoteViewsFixer {
      private static final String TAG = NotificationCompat.TAG;
      private final WidthCompat mWidthCompat;
      private int notification_min_height, notification_max_height, notification_mid_height;
      private int notification_panel_width;
      private int notification_side_padding;
      private int notification_padding;
  
      private final HashMap<String, Bitmap> mImages = new HashMap<>();
      private NotificationCompat mNotificationCompat;
  
      RemoteViewsFixer(NotificationCompat notificationCompat) {
          mWidthCompat = new WidthCompat();
          mNotificationCompat = notificationCompat;
      }
  
      View toView(final Context context, RemoteViews remoteViews, boolean isBig, boolean systemId) {
          View mCache = null;
          try {
              mCache = createView(context, remoteViews, isBig, systemId);
          } catch (Throwable throwable) {
              VLog.w(TAG, "toView 1", throwable);
              try {
                  mCache = LayoutInflater.from(context).inflate(remoteViews.getLayoutId(), null);
              } catch (Throwable e) {
                  VLog.w(TAG, "toView 2", e);
              }
          }
          return mCache;
      }
  
      Bitmap createBitmap(View mCache) {
          if (mCache == null) {
              return null;
          }
          mCache.setDrawingCacheEnabled(true);
          mCache.buildDrawingCache();
          return mCache.getDrawingCache();
      }
  
      private View apply(Context context, RemoteViews remoteViews) {
          View view = null;
          try {
              view = LayoutInflater.from(context).inflate(remoteViews.getLayoutId(), null, false);
              try {
                  Reflect.on(view).call("setTagInternal", Reflect.on("com.android.internal.R$id").get("widget_frame"), remoteViews.getLayoutId());
              } catch (Exception e2) {
                  VLog.w(TAG, "setTagInternal", e2);
              }
          } catch (Exception e) {
              VLog.w(TAG, "inflate", e);
          }
          if (view != null) {
              ArrayList<Object> mActions = Reflect.on(remoteViews).get("mActions");
              if (mActions != null) {
                  VLog.d(TAG, "apply actions:"+mActions.size());
                  for (Object action : mActions) {
                      try {
                          Reflect.on(action).call("apply", view, null, null);
                      } catch (Exception e) {
                          VLog.w(TAG, "apply action", e);
                      }
                  }
              }
          } else {
              VLog.e(TAG, "create views");
          }
          return view;
      }
  
      private View createView(final Context context, RemoteViews remoteViews, boolean isBig, boolean systemId) {
          if (remoteViews == null)
              return null;
          Context base = mNotificationCompat.getHostContext();
          init(base);
          VLog.v(TAG, "createView:big=" + isBig + ",system=" + systemId);
  
          int height = isBig ? notification_max_height : notification_min_height;
          int width = mWidthCompat.getNotificationWidth(base, notification_panel_width, height,
                  notification_side_padding);
          VLog.v(TAG, "createView:getNotificationWidth=" + width);
          ViewGroup frameLayout = new FrameLayout(context);
          VLog.v(TAG, "createView:apply");
  
          View view1 = apply(context, remoteViews);
  
          FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                  ViewGroup.LayoutParams.MATCH_PARENT);
          params.gravity = Gravity.CENTER_VERTICAL;
          frameLayout.addView(view1, params);
          if (view1 instanceof ViewGroup) {
              VLog.v(TAG, "createView:fixTextView");
              fixTextView((ViewGroup) view1);
          }
          int mode;
          //TODO need adaptation
          if (systemId) {
              mode = View.MeasureSpec.EXACTLY;
          } else {
              if (isBig) {
                  mode = View.MeasureSpec.AT_MOST;
              } else {
                  mode = View.MeasureSpec.EXACTLY;
              }
          }
          VLog.v(TAG, "createView:layout");
          View mCache = frameLayout;
          mCache.layout(0, 0, width, height);
          mCache.measure(View.MeasureSpec.makeMeasureSpec(width, View.MeasureSpec.EXACTLY),
                  View.MeasureSpec.makeMeasureSpec(height, mode));
          mCache.layout(0, 0, width, mCache.getMeasuredHeight());
          VLog.v(TAG, "notification:systemId=" + systemId + ",max=%d/%d, szie=%d/%d", width, height,
                  mCache.getMeasuredWidth(), mCache.getMeasuredHeight());
          return mCache;
      }
  
      private void fixTextView(ViewGroup viewGroup) {
          int count = viewGroup.getChildCount();
          for (int i = 0; i < count; i++) {
              View v = viewGroup.getChildAt(i);
              if (v instanceof TextView) {
                  TextView tv = (TextView) v;
                  if (isSingleLine(tv)) {
                      tv.setSingleLine(false);
                      tv.setMaxLines(1);
                  }
              } else if (v instanceof ViewGroup) {
                  fixTextView((ViewGroup) v);
              }
          }
      }
  
      private boolean isSingleLine(TextView textView) {
          boolean singleLine;
          try {
              singleLine = Reflect.on(textView).get("mSingleLine");
          } catch (Exception e) {
              singleLine = (textView.getInputType() & EditorInfo.TYPE_TEXT_FLAG_MULTI_LINE) != 0;
          }
          return singleLine;
      }
  
      public RemoteViews makeRemoteViews(String key, Context pluginContext, RemoteViews contentView, boolean isBig, boolean click) {
          if (contentView == null) {
              return null;
          }
          final boolean systemId = false;
          final PendIntentCompat pendIntentCompat = new PendIntentCompat(contentView);
          final int layoutId;
          if (!click || pendIntentCompat.findPendIntents() <= 0) {
              layoutId = R.layout.custom_notification_lite;
          } else {
              layoutId = R.layout.custom_notification;
          }
          VLog.v(TAG, "createviews id = " + layoutId);
          //make a remoteViews
          RemoteViews remoteViews = new RemoteViews(mNotificationCompat.getHostContext().getPackageName(), layoutId);
          VLog.v(TAG, "remoteViews to view");
          View cache = toView(pluginContext, contentView, isBig, systemId);
          // remoteViews to bitmap
          VLog.v(TAG, "start createBitmap");
          final Bitmap bmp = createBitmap(cache);
          if (bmp == null) {
              VLog.e(TAG, "bmp is null,contentView=" + contentView);
              // return null; //ignore notification
          } else {
              VLog.v(TAG, "bmp w=" + bmp.getWidth() + ",h=" + bmp.getHeight());
          }
          Bitmap old;
          synchronized (mImages) {
              old = mImages.get(key);
          }
          if (old != null && !old.isRecycled()) {
              VLog.v(TAG, "recycle " + key);
              old.recycle();
          }
          remoteViews.setImageViewBitmap(R.id.im_main, bmp);
          VLog.v(TAG, "createview " + key);
          synchronized (mImages) {
              mImages.put(key, bmp);
          }
          //notification's click
          if (click) {
              if (layoutId == R.layout.custom_notification) {
                  VLog.v(TAG, "start setPendIntent");
                  try {
                      pendIntentCompat.setPendIntent(remoteViews,
                              toView(mNotificationCompat.getHostContext(), remoteViews, isBig, systemId),
                              cache);
                  } catch (Exception e) {
                      VLog.e(TAG, "setPendIntent error", e);
                  }
              }
          }
          return remoteViews;
      }
  
      private boolean init = false;
  
      private void init(Context context) {
          if (init) return;
          init = true;
          if (notification_panel_width == 0) {
              Context systemUi = null;
              try {
                  systemUi = context.createPackageContext(NotificationCompat.SYSTEM_UI_PKG, Context.CONTEXT_IGNORE_SECURITY);
              } catch (PackageManager.NameNotFoundException e) {
              }
              if (Build.VERSION.SDK_INT <= 19) {
                  notification_side_padding = 0;
              } else {
                  notification_side_padding = getDimem(context, systemUi, "notification_side_padding",
                          R.dimen.notification_side_padding);
              }
              notification_panel_width = getDimem(context, systemUi, "notification_panel_width",
                      R.dimen.notification_panel_width);
              if (notification_panel_width <= 0) {
                  notification_panel_width = context.getResources().getDisplayMetrics().widthPixels;
              }
              notification_min_height = getDimem(context, systemUi, "notification_min_height",
                      R.dimen.notification_min_height);
              // getDimem(context, systemUi, "notification_row_min_height", 0);
              // if (notification_min_height == 0) {
              // notification_min_height =
              // }
              notification_max_height = getDimem(context, systemUi, "notification_max_height",
                      R.dimen.notification_max_height);
              notification_mid_height = getDimem(context, systemUi, "notification_mid_height",
                      R.dimen.notification_mid_height);
              notification_padding = getDimem(context, systemUi, "notification_padding", R.dimen.notification_padding);
              // notification_collapse_second_card_padding
          }
      }
  
      private int getDimem(Context context, Context sysContext, String name, int defId) {
          if (sysContext != null) {
              int id = sysContext.getResources().getIdentifier(name, "dimen", NotificationCompat.SYSTEM_UI_PKG);
              if (id != 0) {
                  try {
                      return Math.round(sysContext.getResources().getDimension(id));
                  } catch (Exception e) {
  
                  }
              }
          }
          // VLog.w(TAG, "use my dimen:" + name);
          return defId == 0 ? 0 : Math.round(context.getResources().getDimension(defId));
      }
  
  }
  