package com.genymobile.scrcpy.wrappers;

import com.genymobile.scrcpy.Ln;

import android.content.ClipData;
import android.os.IInterface;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class ClipboardManager {
    private final IInterface manager;
    private Method getPrimaryClipMethod;
    private Method setPrimaryClipMethod;

    public ClipboardManager(IInterface manager) {
        this.manager = manager;
    }

    private Method getGetPrimaryClipMethod() {
        if (getPrimaryClipMethod == null) {
            try {
                getPrimaryClipMethod = manager.getClass().getMethod("getPrimaryClip", String.class);
            } catch (NoSuchMethodException e) {
                Ln.e("Could not find method", e);
            }
        }
        return getPrimaryClipMethod;
    }

    private Method getSetPrimaryClipMethod() {
        if (setPrimaryClipMethod == null) {
            try {
                setPrimaryClipMethod = manager.getClass().getMethod("setPrimaryClip", ClipData.class, String.class);
            } catch (NoSuchMethodException e) {
                Ln.e("Could not find method", e);
            }
        }
        return setPrimaryClipMethod;
    }

    public CharSequence getText() {
        Method method = getGetPrimaryClipMethod();
        if (method == null) {
            return null;
        }
        try {
            ClipData clipData = (ClipData) method.invoke(manager, "com.android.shell");
            if (clipData == null || clipData.getItemCount() == 0) {
                return null;
            }
            return clipData.getItemAt(0).getText();
        } catch (InvocationTargetException | IllegalAccessException e) {
            Ln.e("Could not invoke " + method.getName(), e);
            return null;
        }
    }

    public void setText(CharSequence text) {
        Method method = getSetPrimaryClipMethod();
        if (method == null) {
            return;
        }
        ClipData clipData = ClipData.newPlainText(null, text);
        try {
            method.invoke(manager, clipData, "com.android.shell");
        } catch (InvocationTargetException | IllegalAccessException e) {
            Ln.e("Could not invoke " + method.getName(), e);
        }
    }
}

@@ -250,16 +250,86 @@
 nager %7B%0A
+%0A    private static final String PACKAGE_NAME = %22com.android.shell%22;%0A%0A
     priv
@@ -1530,35 +1530,28 @@
 anager, 
-%22com.android.shell%22
+PACKAGE_NAME
 );%0A     
@@ -2162,35 +2162,28 @@
 ipData, 
-%22com.android.shell%22
+PACKAGE_NAME
 );%0A     

Extract String literal to static constant