/*
 * Copyright 2018 Hippo Seven
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.hippo.widget;

import android.content.Context;
import android.graphics.Canvas;
import android.os.Build;
import android.support.design.widget.TextInputEditText;
import android.util.AttributeSet;
import android.widget.TextView;
import com.hippo.util.ExceptionUtils;
import java.lang.reflect.Field;

// Avoid crash on some Meizu devices
// https://github.com/android-in-china/Compatibility/issues/11
// https://stackoverflow.com/questions/51891415/nullpointerexception-on-meizu-devices-in-editor-updatecursorpositionmz/52001305
public class HackyTextInputEditText extends TextInputEditText {

  public HackyTextInputEditText(Context context, AttributeSet attrs) {
    super(context, attrs);
  }

  @Override
  public CharSequence getHint() {
    boolean isMeizu = Build.MANUFACTURER.toLowerCase().contains("meizu");
    boolean isPreP = Build.VERSION.SDK_INT < Build.VERSION_CODES.P;

    if (isMeizu && isPreP) {
      try {
        return getSuperHint();
      } catch (Throwable e) {
        ExceptionUtils.throwIfFatal(e);
        return super.getHint();
      }
    } else {
      return super.getHint();
    }
  }

  public CharSequence getSuperHint() throws NoSuchFieldException, IllegalAccessException {
    Field field = TextView.class.getDeclaredField("mHint");
    field.setAccessible(true);
    return (CharSequence) field.get(this);
  }

  // Some devices still crash
  @Override
  protected void onDraw(Canvas canvas) {
    try {
      super.onDraw(canvas);
    } catch (Throwable t) {
      ExceptionUtils.throwIfFatal(t);
    }
  }
}

@@ -652,65 +652,8 @@
 xt;%0A
-import android.graphics.Canvas;%0Aimport android.os.Build;%0A
 impo
@@ -839,16 +839,49 @@
 t.Field;
+%0Aimport java.lang.reflect.Method;
 %0A%0A// Avo
@@ -1174,371 +1174,510 @@
 %0A  p
-ublic HackyTextInputEditText(Context context, AttributeSet attrs) %7B%0A    super(context, attrs);%0A  %7D%0A%0A  @Override%0A  public CharSequence getHint() %7B%0A    boolean isMeizu = Build.MANUFACTURER.toLowerCase().contains(%22meizu%22);%0A    boolean isPreP = Build.VERSION.SDK_INT %3C Build.VERSION_CODES.P;%0A%0A    if (isMeizu && isPreP) %7B%0A      try %7B%0A        return getSuperHint();%0A  
+rivate static final boolean HAS_METHOD_UPDATE_CURSOR_POSITION_MZ;%0A  private static final Field FIELD_M_HINT;%0A%0A  static %7B%0A    boolean hasMethodUpdateCursorPositionMz = false;%0A    try %7B%0A      Class%3C?%3E clazz = ClassLoader.getSystemClassLoader().loadClass(%22android.widget.Editor%22);%0A      Method%5B%5D methods = clazz.getDeclaredMethods();%0A      for (Method method : methods) %7B%0A        if (%22updateCursorPositionMz%22.equals(method.getName())) %7B%0A          hasMethodUpdateCursorPositionMz = true;%0A        %7D%0A      %7D%0A
     
@@ -1696,26 +1696,24 @@
 owable e) %7B%0A
-  
       Except
@@ -1746,204 +1746,113 @@
     
+%7D%0A%0A
     
-return super.getHint();%0A      %7D%0A    %7D else %7B%0A      return super.getHint();%0A    %7D%0A  %7D%0A%0A  public CharSequence getSuperHint() throws NoSuchFieldException, IllegalAccessException %7B%0A    Field
+Field fieldMHint = null;%0A    if (hasMethodUpdateCursorPositionMz) %7B%0A      try %7B%0A       
  field
+MHint
  = T
@@ -1888,24 +1888,28 @@
 d(%22mHint%22);%0A
+    
     field.se
@@ -1905,16 +1905,21 @@
    field
+MHint
 .setAcce
@@ -1940,135 +1940,424 @@
     
-return (CharSequence) field.get(this);%0A  %7D%0A%0A  // Some devices still crash%0A  @Override%0A  protected void onDraw(Canvas canvas
+  %7D catch (Throwable e) %7B%0A        ExceptionUtils.throwIfFatal(e);%0A      %7D%0A    %7D%0A%0A    HAS_METHOD_UPDATE_CURSOR_POSITION_MZ = hasMethodUpdateCursorPositionMz;%0A    FIELD_M_HINT = fieldMHint;%0A  %7D%0A%0A  public HackyTextInputEditText(Context context, AttributeSet attrs) %7B%0A    super(context, attrs);%0A  %7D%0A%0A  @Override%0A  public CharSequence getHint() %7B%0A    if (HAS_METHOD_UPDATE_CURSOR_POSITION_MZ && FIELD_M_HINT != null
 ) %7B%0A
+  
     
@@ -2372,30 +2372,35 @@
     
-super.onDraw(canvas
+  return getSuperHint(
 );%0A
+  
     
@@ -2418,17 +2418,17 @@
 rowable 
-t
+e
 ) %7B%0A    
@@ -2421,32 +2421,34 @@
 able e) %7B%0A      
+  
 ExceptionUtils.t
@@ -2463,17 +2463,225 @@
 tal(
-t);%0A    %7D
+e);%0A        return super.getHint();%0A      %7D%0A    %7D else %7B%0A      return super.getHint();%0A    %7D%0A  %7D%0A%0A  private CharSequence getSuperHint() throws IllegalAccessException %7B%0A    return (CharSequence) FIELD_M_HINT.get(this);
 %0A  %7D

Check updateCursorPositionMz method instead of device manufacturer