Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 68ff174b authored by Deepanshu Gupta's avatar Deepanshu Gupta Committed by Android Git Automerger
Browse files

am 2b99b5da: am c9862b44: An ugly hack to render CalendarView. [DO NOT MERGE]

* commit '2b99b5da':
  An ugly hack to render CalendarView. [DO NOT MERGE]
parents d9600c98 2b99b5da
Loading
Loading
Loading
Loading
+2 −0
Original line number Original line Diff line number Diff line
@@ -112,6 +112,8 @@ public class AsmAnalyzer {
            mGen.setDeps(deps);
            mGen.setDeps(deps);
            mGen.setCopyFiles(filesFound);
            mGen.setCopyFiles(filesFound);
            mGen.setRewriteMethodCallClasses(mReplaceMethodCallClasses);
            mGen.setRewriteMethodCallClasses(mReplaceMethodCallClasses);
            // hack hack hack
            mGen.mSimpleMonthViewReader = zipClasses.get(AsmGenerator.SIMPLE_MONTH_VIEW);
        }
        }
    }
    }


+8 −1
Original line number Original line Diff line number Diff line
@@ -77,6 +77,9 @@ public class AsmGenerator {
    /** Methods to inject. FQCN of class in which method should be injected => runnable that does
    /** Methods to inject. FQCN of class in which method should be injected => runnable that does
     * the injection. */
     * the injection. */
    private final Map<String, ICreateInfo.InjectMethodRunnable> mInjectedMethodsMap;
    private final Map<String, ICreateInfo.InjectMethodRunnable> mInjectedMethodsMap;
    // A hack to do some modifications to simple month view.
    static final String SIMPLE_MONTH_VIEW = "android/widget/SimpleMonthView";
    ClassReader mSimpleMonthViewReader;


    /**
    /**
     * Creates a new generator that can generate the output JAR with the stubbed classes.
     * Creates a new generator that can generate the output JAR with the stubbed classes.
@@ -204,7 +207,7 @@ public class AsmGenerator {
     * Utility that returns the internal ASM class name from a fully qualified binary class
     * Utility that returns the internal ASM class name from a fully qualified binary class
     * name. E.g. it returns android/view/View from android.view.View.
     * name. E.g. it returns android/view/View from android.view.View.
     */
     */
    String binaryToInternalClassName(String className) {
    static String binaryToInternalClassName(String className) {
        if (className == null) {
        if (className == null) {
            return null;
            return null;
        } else {
        } else {
@@ -380,6 +383,10 @@ public class AsmGenerator {
            }
            }
        }
        }


        if (SIMPLE_MONTH_VIEW.equals(className)) {
            cv = new SimpleMonthViewAdapter(cv);
        }

        cr.accept(cv, 0);
        cr.accept(cv, 0);
        return cw.toByteArray();
        return cw.toByteArray();
    }
    }
+90 −0
Original line number Original line Diff line number Diff line
/*
 * Copyright (C) 2015 The Android Open Source Project
 *
 * 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.android.tools.layoutlib.create;

import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.FieldVisitor;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;

import java.text.SimpleDateFormat;

import static com.android.tools.layoutlib.create.AsmGenerator.binaryToInternalClassName;

/**
 * A very ugly hack to transform all references to {@link java.text.SimpleDateFormat} in {@code
 * android.widget.SimpleMonthView} to {@code com.ibm.icu.text.SimpleDateFormat}.
 */
public class SimpleMonthViewAdapter extends ClassVisitor {

    private static final String JAVA_SDF_DESC = Type.getDescriptor(SimpleDateFormat.class);
    private static final String JAVA_SDF_INTERNAL_NAME =
            binaryToInternalClassName(SimpleDateFormat.class.getName());
    private static final String ICU_SDF_INTERNAL_NAME = "com/ibm/icu/text/SimpleDateFormat";

    public SimpleMonthViewAdapter(ClassVisitor cv) {
        super(Opcodes.ASM4, cv);
    }

    @Override
    public FieldVisitor visitField(int access, String name, String desc, String signature,
            Object value) {
        if (JAVA_SDF_DESC.equals(desc)) {
            desc = "L" + ICU_SDF_INTERNAL_NAME + ";";
        }
        return super.visitField(access, name, desc, signature, value);
    }

    @Override
    public MethodVisitor visitMethod(int access, String name, String desc, String signature,
            String[] exceptions) {
        return new MyMethodVisitor(super.visitMethod(access, name, desc, signature, exceptions));
    }

    private static class MyMethodVisitor extends MethodVisitor {
        public MyMethodVisitor(MethodVisitor mv) {
            super(Opcodes.ASM4, mv);
        }

        @Override
        public void visitTypeInsn(int opcode, String type) {
            if (JAVA_SDF_INTERNAL_NAME.equals(type) && opcode == Opcodes.NEW) {
                type = ICU_SDF_INTERNAL_NAME;
            }
            super.visitTypeInsn(opcode, type);
        }

        @Override
        public void visitMethodInsn(int opcode, String owner, String name, String desc) {
            if (JAVA_SDF_INTERNAL_NAME.equals(owner)) {
                owner = ICU_SDF_INTERNAL_NAME;
            }
            super.visitMethodInsn(opcode, owner, name, desc);
        }

        @Override
        public void visitFieldInsn(int opcode, String owner, String name, String desc) {
            if (JAVA_SDF_DESC.equals(desc) &&
                    (opcode == Opcodes.PUTFIELD || opcode == Opcodes.GETFIELD) &&
                    name.equals("mDayFormatter")) {
                desc = "L" + ICU_SDF_INTERNAL_NAME + ";";
            }
            super.visitFieldInsn(opcode, owner, name, desc);
        }
    }
}