<commit_before>package com.limpoxe.fairy.manager;

import android.annotation.TargetApi;
import android.content.ContentProvider;
import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.CancellationSignal;
import android.os.Handler;
import android.os.Looper;
import android.os.ParcelFileDescriptor;
import android.os.Process;
import android.util.Log;

import com.limpoxe.fairy.content.LoadedPlugin;
import com.limpoxe.fairy.content.PluginDescriptor;
import com.limpoxe.fairy.core.FairyGlobal;
import com.limpoxe.fairy.core.PluginLauncher;
import com.limpoxe.fairy.manager.mapping.PluginStubBinding;
import com.limpoxe.fairy.manager.mapping.StubExact;
import com.limpoxe.fairy.manager.mapping.StubMappingProcessor;
import com.limpoxe.fairy.util.LogUtil;

import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Collection;

import static com.limpoxe.fairy.core.bridge.ProviderClientProxy.CALL_PROXY_KEY;
import static com.limpoxe.fairy.core.bridge.ProviderClientProxy.TARGET_URL;

/**
 * Created by cailiming on 16/3/11.
 *
 * 利用ContentProvider实现同步跨进程调用
 *
 * 注意： ContentProvider 的方法可能不是在主线程中执行的。
 */
public class PluginManagerProvider extends ContentProvider {

    private static Uri CONTENT_URI;

    public static final String ACTION_INSTALL = "install";
    public static final String INSTALL_RESULT = "install_result";

    public static final String ACTION_REMOVE = "remove";
    public static final String REMOVE_RESULT = "remove_result";

    public static final String ACTION_REMOVE_ALL = "remove_all";
    public static final String REMOVE_ALL_RESULT = "remove_all_result";

    public static final String ACTION_STOP = "stop_plugin";
    public static final String STOP_RESULT = "stop_plugin_result";

    public static final String ACTION_QUERY_BY_ID = "query_by_id";
    public static final String QUERY_BY_ID_RESULT = "query_by_id_result";

    public static final String ACTION_QUERY_BY_CLASS_NAME = "query_by_class_name";
    public static final String QUERY_BY_CLASS_NAME_RESULT = "query_by_class_name_result";

    public static final String ACTION_QUERY_BY_FRAGMENT_ID = "query_by_fragment_id";
    public static final String QUERY_BY_FRAGMENT_ID_RESULT = "query_by_fragment_id_result";

    public static final String ACTION_QUERY_ALL = "query_all";
    public static final String QUERY_ALL_RESULT = "query_all_result";

    public static final String ACTION_BIND_ACTIVITY = "bind_activity";
    public static final String BIND_ACTIVITY_RESULT = "bind_activity_result";

    public static final String ACTION_UNBIND_ACTIVITY = "unbind_activity";
    public static final String UNBIND_ACTIVITY_RESULT = "unbind_activity_result";

    public static final String ACTION_BIND_SERVICE = "bind_service";
    public static final String BIND_SERVICE_RESULT = "bind_service_result";

    public static final String ACTION_GET_BINDED_SERVICE = "get_binded_service";
    public static final String GET_BINDED_SERVICE_RESULT = "get_binded_service_result";

    public static final String ACTION_UNBIND_SERVICE = "unbind_service";
    public static final String UNBIND_SERVICE_RESULT = "unbind_service_result";

    public static final String ACTION_BIND_RECEIVER = "bind_receiver";
    public static final String BIND_RECEIVER_RESULT = "bind_receiver_result";

    public static final String ACTION_IS_EXACT = "is_exact";
    public static final String IS_EXACT_RESULT = "is_exact_result";

    public static final String ACTION_IS_STUB = "is_stub";
    public static final String IS_STUB_RESULT = "is_stub_result";

    public static final String ACTION_IS_PLUGIN_RUNNING = "is_plugin_running";
    public static final String IS_PLUGIN_RUNNING_RESULT = "is_plugin_running_result";

    public static final String ACTION_WAKEUP_PLUGIN = "wakeup_plugin";
    public static final String WAKEUP_PLUGIN_RESULT = "wakeup_plugin_result";

    public static final String ACTION_DUMP_SERVICE_INFO = "dump_service_info";
    public static final String DUMP_SERVICE_INFO_RESULT = "dump_service_info_result";

    public static final String ACTION_REBOOT_PLUGIN_PROCESS = "reboot_plugin_process";


    private PluginManagerService managerService;
    private PluginStatusChangeListener changeListener;
    private Handler mainHandler;

    public static Uri buildUri() {
        if (CONTENT_URI == null) {
            CONTENT_URI = Uri.parse("content://"+ FairyGlobal.getHostApplication().getPackageName() + ".manager" + "/call");
        }
        return CONTENT_URI;
    }

    public PluginManagerProvider() {
        Log.e("PluginManagerProvider", "create instance");
    }

    @Override
    public boolean onCreate() {

        Log.d("PluginManagerProvider", "onCreate, Thread id " + Thread.currentThread().getId() + " name " + Thread.currentThread().getName() + " pid " + Process.myPid());

        mainHandler = new Handler(Looper.getMainLooper());
        managerService = new PluginManagerService();
        changeListener = new PluginCallbackImpl();
        managerService.loadInstalledPlugins();

        return true;
    }

    @Override
    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
        Uri targetUrl = Uri.parse(uri.getQueryParameter(TARGET_URL));
        return getContext().getContentResolver().query(targetUrl, projection, selection, selectionArgs, sortOrder);
    }

    @TargetApi(Build.VERSION_CODES.O)
    @Override
    public Cursor query(Uri uri, String[] projection, Bundle queryArgs, CancellationSignal cancellationSignal) {
        Uri targetUrl = Uri.parse(uri.getQueryParameter(TARGET_URL));
        return getContext().getContentResolver().query(targetUrl, projection, queryArgs, cancellationSignal);
    }

    @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
    @Override
    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder, CancellationSignal cancellationSignal) {
        Uri targetUrl = Uri.parse(uri.getQueryParameter(TARGET_URL));
        return getContext().getContentResolver().query(targetUrl, projection, selection, selectionArgs, sortOrder, cancellationSignal);
    }

    @Override
    public String getType(Uri uri) {
        Uri targetUrl = Uri.parse(uri.getQueryParameter(TARGET_URL));
        return getContext().getContentResolver().getType(targetUrl);
    }

    @Override
    public Uri insert(Uri uri, ContentValues values) {
        Uri targetUrl = Uri.parse(uri.getQueryParameter(TARGET_URL));
        return getContext().getContentResolver().insert(targetUrl, values);
    }

    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {
        Uri targetUrl = Uri.parse(uri.getQueryParameter(TARGET_URL));
        return getContext().getContentResolver().delete(targetUrl, selection, selectionArgs);
    }

    @Override
    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
        Uri targetUrl = Uri.parse(uri.getQueryParameter(TARGET_URL));
        return getContext().getContentResolver().update(targetUrl, values, selection, selectionArgs);
    }

    @Override
    public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {
        Uri targetUrl = Uri.parse(uri.getQueryParameter(TARGET_URL));
        LogUtil.d("openFile", "uri", uri.toString(), "targetUrl", targetUrl);
        return getContext().getContentResolver().openFileDescriptor(targetUrl, mode);
    }

    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
    @Override
    public Bundle call(String method, String arg, Bundle extras) {

        if (Build.VERSION.SDK_INT >= 19) {
            LogUtil.v("callingPackage = ", getCallingPackage());
        }

        LogUtil.d("跨进程调用统计",<commit_msg>[优化]删除LOG<commit_after>package com.limpoxe.fairy.manager;

import android.annotation.TargetApi;
import android.content.ContentProvider;
import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.CancellationSignal;
import android.os.Handler;
import android.os.Looper;
import android.os.ParcelFileDescriptor;
import android.os.Process;
import android.util.Log;

import com.limpoxe.fairy.content.LoadedPlugin;
import com.limpoxe.fairy.content.PluginDescriptor;
import com.limpoxe.fairy.core.FairyGlobal;
import com.limpoxe.fairy.core.PluginLauncher;
import com.limpoxe.fairy.manager.mapping.PluginStubBinding;
import com.limpoxe.fairy.manager.mapping.StubExact;
import com.limpoxe.fairy.manager.mapping.StubMappingProcessor;
import com.limpoxe.fairy.util.LogUtil;

import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Collection;

import static com.limpoxe.fairy.core.bridge.ProviderClientProxy.CALL_PROXY_KEY;
import static com.limpoxe.fairy.core.bridge.ProviderClientProxy.TARGET_URL;

/**
 * Created by cailiming on 16/3/11.
 *
 * 利用ContentProvider实现同步跨进程调用
 *
 * 注意： ContentProvider 的方法可能不是在主线程中执行的。
 */
public class PluginManagerProvider extends ContentProvider {

    private static Uri CONTENT_URI;

    public static final String ACTION_INSTALL = "install";
    public static final String INSTALL_RESULT = "install_result";

    public static final String ACTION_REMOVE = "remove";
    public static final String REMOVE_RESULT = "remove_result";

    public static final String ACTION_REMOVE_ALL = "remove_all";
    public static final String REMOVE_ALL_RESULT = "remove_all_result";

    public static final String ACTION_STOP = "stop_plugin";
    public static final String STOP_RESULT = "stop_plugin_result";

    public static final String ACTION_QUERY_BY_ID = "query_by_id";
    public static final String QUERY_BY_ID_RESULT = "query_by_id_result";

    public static final String ACTION_QUERY_BY_CLASS_NAME = "query_by_class_name";
    public static final String QUERY_BY_CLASS_NAME_RESULT = "query_by_class_name_result";

    public static final String ACTION_QUERY_BY_FRAGMENT_ID = "query_by_fragment_id";
    public static final String QUERY_BY_FRAGMENT_ID_RESULT = "query_by_fragment_id_result";

    public static final String ACTION_QUERY_ALL = "query_all";
    public static final String QUERY_ALL_RESULT = "query_all_result";

    public static final String ACTION_BIND_ACTIVITY = "bind_activity";
    public static final String BIND_ACTIVITY_RESULT = "bind_activity_result";

    public static final String ACTION_UNBIND_ACTIVITY = "unbind_activity";
    public static final String UNBIND_ACTIVITY_RESULT = "unbind_activity_result";

    public static final String ACTION_BIND_SERVICE = "bind_service";
    public static final String BIND_SERVICE_RESULT = "bind_service_result";

    public static final String ACTION_GET_BINDED_SERVICE = "get_binded_service";
    public static final String GET_BINDED_SERVICE_RESULT = "get_binded_service_result";

    public static final String ACTION_UNBIND_SERVICE = "unbind_service";
    public static final String UNBIND_SERVICE_RESULT = "unbind_service_result";

    public static final String ACTION_BIND_RECEIVER = "bind_receiver";
    public static final String BIND_RECEIVER_RESULT = "bind_receiver_result";

    public static final String ACTION_IS_EXACT = "is_exact";
    public static final String IS_EXACT_RESULT = "is_exact_result";

    public static final String ACTION_IS_STUB = "is_stub";
    public static final String IS_STUB_RESULT = "is_stub_result";

    public static final String ACTION_IS_PLUGIN_RUNNING = "is_plugin_running";
    public static final String IS_PLUGIN_RUNNING_RESULT = "is_plugin_running_result";

    public static final String ACTION_WAKEUP_PLUGIN = "wakeup_plugin";
    public static final String WAKEUP_PLUGIN_RESULT = "wakeup_plugin_result";

    public static final String ACTION_DUMP_SERVICE_INFO = "dump_service_info";
    public static final String DUMP_SERVICE_INFO_RESULT = "dump_service_info_result";

    public static final String ACTION_REBOOT_PLUGIN_PROCESS = "reboot_plugin_process";


    private PluginManagerService managerService;
    private PluginStatusChangeListener changeListener;
    private Handler mainHandler;

    public static Uri buildUri() {
        if (CONTENT_URI == null) {
            CONTENT_URI = Uri.parse("content://"+ FairyGlobal.getHostApplication().getPackageName() + ".manager" + "/call");
        }
        return CONTENT_URI;
    }

    public PluginManagerProvider() {
        Log.e("PluginManagerProvider", "create instance");
    }

    @Override
    public boolean onCreate() {

        Log.d("PluginManagerProvider", "onCreate, Thread id " + Thread.currentThread().getId() + " name " + Thread.currentThread().getName() + " pid " + Process.myPid());

        mainHandler = new Handler(Looper.getMainLooper());
        managerService = new PluginManagerService();
        changeListener = new PluginCallbackImpl();
        managerService.loadInstalledPlugins();

        return true;
    }

    @Override
    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
        Uri targetUrl = Uri.parse(uri.getQueryParameter(TARGET_URL));
        return getContext().getContentResolver().query(targetUrl, projection, selection, selectionArgs, sortOrder);
    }

    @TargetApi(Build.VERSION_CODES.O)
    @Override
    public Cursor query(Uri uri, String[] projection, Bundle queryArgs, CancellationSignal cancellationSignal) {
        Uri targetUrl = Uri.parse(uri.getQueryParameter(TARGET_URL));
        return getContext().getContentResolver().query(targetUrl, projection, queryArgs, cancellationSignal);
    }

    @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
    @Override
    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder, CancellationSignal cancellationSignal) {
        Uri targetUrl = Uri.parse(uri.getQueryParameter(TARGET_URL));
        return getContext().getContentResolver().query(targetUrl, projection, selection, selectionArgs, sortOrder, cancellationSignal);
    }

    @Override
    public String getType(Uri uri) {
        Uri targetUrl = Uri.parse(uri.getQueryParameter(TARGET_URL));
        return getContext().getContentResolver().getType(targetUrl);
    }

    @Override
    public Uri insert(Uri uri, ContentValues values) {
        Uri targetUrl = Uri.parse(uri.getQueryParameter(TARGET_URL));
        return getContext().getContentResolver().insert(targetUrl, values);
    }

    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {
        Uri targetUrl = Uri.parse(uri.getQueryParameter(TARGET_URL));
        return getContext().getContentResolver().delete(targetUrl, selection, selectionArgs);
    }

    @Override
    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
        Uri targetUrl = Uri.parse(uri.getQueryParameter(TARGET_URL));
        return getContext().getContentResolver().update(targetUrl, values, selection, selectionArgs);
    }

    @Override
    public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {
        Uri targetUrl = Uri.parse(uri.getQueryParameter(TARGET_URL));
        LogUtil.d("openFile", "uri", uri.toString(), "targetUrl", targetUrl);
        return getContext().getContentResolver().openFileDescriptor(targetUrl, mode);
    }

    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
    @Override
    public Bundle call(String method, String arg, Bundle extras) {

        if (Build.VERSION.SDK_INT >= 19) {
            //LogUtil.v("callingPackage = ", getCallingPackage());
        }

        LogUtil.d("跨进程调用统计",
{'fraction_non_alphanumeric': 0.08723809523809524, 'fraction_numerical': 0.0008888888888888889, 'mean_word_length': 4.61132882080513, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3875577', 'n_tokens_mistral': 4610, 'n_tokens_neox': 4514, 'n_words': 1045}