BigImgTransformer.kt 6.0 KB
Newer Older
1
package com.didichuxing.doraemonkit.plugin.classtransformer
J
jackjintai 已提交
2 3

import com.didichuxing.doraemonkit.plugin.DoKitExtUtil
4
import com.didichuxing.doraemonkit.plugin.getMethodExitInsnNodes
5 6
import com.didichuxing.doraemonkit.plugin.isRelease
import com.didichuxing.doraemonkit.plugin.println
J
jackjintai 已提交
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
import com.didiglobal.booster.annotations.Priority
import com.didiglobal.booster.transform.TransformContext
import com.didiglobal.booster.transform.asm.ClassTransformer
import com.didiglobal.booster.transform.asm.className
import com.google.auto.service.AutoService
import org.objectweb.asm.Opcodes.*
import org.objectweb.asm.tree.ClassNode
import org.objectweb.asm.tree.InsnList
import org.objectweb.asm.tree.MethodInsnNode
import org.objectweb.asm.tree.VarInsnNode

/**
 * ================================================
 * 作    者:jint(金台)
 * 版    本:1.0
 * 创建日期:2020/5/14-18:07
 * 描    述:wiki:https://juejin.im/post/5e8d87c4f265da47ad218e6b
 * 修订历史:
 * ================================================
 */
J
jackjintai 已提交
27
@Priority(1)
J
jackjintai 已提交
28 29 30 31
@AutoService(ClassTransformer::class)
class BigImgTransformer : ClassTransformer {

    override fun transform(context: TransformContext, klass: ClassNode): ClassNode {
32 33 34
        if (context.isRelease()) {
            return klass
        }
35

J
jackjintai 已提交
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
        if (!DoKitExtUtil.dokitPluginSwitchOpen()) {
            return klass
        }

        if (!DoKitExtUtil.commExt.bigImgSwitch) {
            return klass
        }

        if (DoKitExtUtil.ignorePackageNames(klass.className)) {
            return klass
        }


        val className = klass.className
        //glide
        if (className == "com.bumptech.glide.request.SingleRequest") {
            klass.methods.find { methodNode ->
                (methodNode.name == "init" || methodNode.name == "<init>") && methodNode.desc != null
            }.let { methodNode ->
                //函数结束的地方插入
56
                methodNode?.instructions?.getMethodExitInsnNodes()?.forEach {
57
                    "hook glide  succeed: ${className}_${methodNode.name}_${methodNode.desc}".println()
58
                    methodNode.instructions?.insertBefore(it, createGlideInsnList())
J
jackjintai 已提交
59 60 61 62 63 64 65 66 67 68
                }
            }
        }

        //picasso
        if (className == "com.squareup.picasso.Request") {
            klass.methods.find { methodNode ->
                methodNode.name == "<init>" && methodNode.desc != null
            }.let { methodNode ->
                //函数结束的地方插入
69
                methodNode?.instructions?.getMethodExitInsnNodes()?.forEach {
70
                    "hook picasso  succeed: ${className}_${methodNode.name}_${methodNode.desc}".println()
71
                    methodNode.instructions?.insertBefore(it, createPicassoInsnList())
J
jackjintai 已提交
72 73 74 75 76 77 78 79 80
                }
            }
        }

        //Fresco
        if (className == "com.facebook.imagepipeline.request.ImageRequest") {
            klass.methods.find { methodNode ->
                methodNode.name == "<init>" && methodNode.desc != null
            }.let { methodNode ->
81
                "hook Fresco succeed: ${className}_${methodNode?.name}_${methodNode?.desc}".println()
J
jackjintai 已提交
82 83 84 85 86 87 88 89 90 91
                //函数开始的地方插入
                methodNode?.instructions?.insert(createFrescoInsnList())
            }
        }

        //ImageLoader
        if (className == "com.nostra13.universalimageloader.core.ImageLoadingInfo") {
            klass.methods.find { methodNode ->
                methodNode.name == "<init>" && methodNode.desc != null
            }.let { methodNode ->
92
                "hook ImageLoader  succeed: ${className}_${methodNode?.name}_${methodNode?.desc}".println()
J
jackjintai 已提交
93 94 95 96 97 98 99 100 101 102 103 104
                methodNode?.instructions?.insert(createImageLoaderInsnList())
            }
        }


        return klass
    }

    /**
     * 创建Glide Aop代码指令
     */
    private fun createGlideInsnList(): InsnList {
105 106 107 108 109
        return with(InsnList()) {
            add(VarInsnNode(ALOAD, 0))
            add(MethodInsnNode(INVOKESTATIC, "com/didichuxing/doraemonkit/aop/bigimg/glide/GlideHook", "proxy", "(Ljava/lang/Object;)V", false))
            this
        }
J
jackjintai 已提交
110 111 112 113 114 115
    }

    /**
     * 创建Picasso Aop代码指令
     */
    private fun createPicassoInsnList(): InsnList {
116 117 118 119 120 121
        return with(InsnList()) {
            add(VarInsnNode(ALOAD, 0))
            add(MethodInsnNode(INVOKESTATIC, "com/didichuxing/doraemonkit/aop/bigimg/picasso/PicassoHook", "proxy", "(Ljava/lang/Object;)V", false))
            this
        }

J
jackjintai 已提交
122 123 124 125 126 127 128
    }


    /**
     * 创建Fresco Aop代码指令
     */
    private fun createFrescoInsnList(): InsnList {
129 130 131 132 133 134 135 136 137 138 139
        return with(InsnList()) {
            add(VarInsnNode(ALOAD, 1))
            add(VarInsnNode(ALOAD, 1))
            add(MethodInsnNode(INVOKEVIRTUAL, "com/facebook/imagepipeline/request/ImageRequestBuilder", "getSourceUri", "()Landroid/net/Uri;", false))
            add(VarInsnNode(ALOAD, 1))
            add(MethodInsnNode(INVOKEVIRTUAL, "com/facebook/imagepipeline/request/ImageRequestBuilder", "getPostprocessor", "()Lcom/facebook/imagepipeline/request/Postprocessor;", false))
            add(MethodInsnNode(INVOKESTATIC, "com/didichuxing/doraemonkit/aop/bigimg/fresco/FrescoHook", "proxy", "(Landroid/net/Uri;Lcom/facebook/imagepipeline/request/Postprocessor;)Lcom/facebook/imagepipeline/request/Postprocessor;", false))
            add(MethodInsnNode(INVOKEVIRTUAL, "com/facebook/imagepipeline/request/ImageRequestBuilder", "setPostprocessor", "(Lcom/facebook/imagepipeline/request/Postprocessor;)Lcom/facebook/imagepipeline/request/ImageRequestBuilder;", false))
            this
        }

J
jackjintai 已提交
140 141 142 143 144 145 146
    }


    /**
     * 创建ImageLoader Aop代码指令
     */
    private fun createImageLoaderInsnList(): InsnList {
147 148 149 150 151 152
        return with(InsnList()) {
            add(VarInsnNode(ALOAD, 6))
            add(MethodInsnNode(INVOKESTATIC, "com/didichuxing/doraemonkit/aop/bigimg/imageloader/ImageLoaderHook", "proxy", "(Lcom/nostra13/universalimageloader/core/listener/ImageLoadingListener;)Lcom/nostra13/universalimageloader/core/listener/ImageLoadingListener;", false))
            add(VarInsnNode(ASTORE, 6))
            this
        }
J
jackjintai 已提交
153 154 155
    }
}