package com.tws.plugin.util;
import java.util.List;
import tws.component.log.TwsLog;
import android.app.ActivityManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.pm.PackageManager;
import android.content.pm.ProviderInfo;
import android.text.TextUtils;
import com.tws.plugin.core.PluginApplication;
import com.tws.plugin.core.PluginLoader;
import com.tws.plugin.manager.PluginManagerProvider;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
public class ProcessUtil {
private static final String TAG = "rick_Print:ProcessUtil";
private static Boolean isPluginProcess = null;
private static Boolean isHostProcess = null;
public static String getHostProcessName() {
return PluginLoader.getHostPackageName();
}
public static boolean isPluginProcess(Context context) {
ensure(context);
return isPluginProcess;
}
public static boolean isHostProcess(Context context) {
ensure(context);
return isHostProcess;
}
private static void ensure(Context context) {
// 注意:当前PACE示例的宿主和插件是一个进程,【使用者可以自己按项目需求进行配置配置调整这里的逻辑】
if (isPluginProcess == null) {
String processName = getCurProcessName();
String pluginProcessName = getPluginProcessName(context);
isHostProcess = !TextUtils.isEmpty(processName) && processName.equals(pluginProcessName);
// 这是一个潜规则,插件的进程除PluginManagerProvider的标配外,其他的都统一规定前缀:"HostPackageName:plugin"+"编号";
isPluginProcess = isHostProcess
|| processName.startsWith(PluginApplication.getInstance().getPackageName() + ":plugin"); // 注意这里不能用PluginLoader的Application
TwsLog.d(TAG, "cur processName is " + processName + " | pluginProcessName is" + pluginProcessName);
}
}
public static boolean isPluginProcess() {
return isPluginProcess(PluginLoader.getApplication());
}
public static boolean isHostProcess() {
return isHostProcess(PluginLoader.getApplication());
}
private static String getCurProcessName() {
BufferedReader mBufferedReader = null;
final int pid = android.os.Process.myPid();
TwsLog.d(TAG, "android.os.Process.myPid is " + pid);
try {
File file = new File("proc/" + pid + "/" + "cmdline");
mBufferedReader = new BufferedReader(new FileReader(file));
String processName = mBufferedReader.readLine().trim();
mBufferedReader.close();
return processName;
} catch (Exception e) {
e.printStackTrace();
} finally {
if (mBufferedReader != null) {
try {
mBufferedReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return "";
}
public static String getPluginProcessName(Context context) {
try {
// 这里取个巧, 直接查询ContentProvider的信息中包含的processName
// 因为Contentprovider是被配置在插件进程的.
// 但是这个api只支持9及以上,
ProviderInfo pinfo = context.getPackageManager().getProviderInfo(
new ComponentName(context, PluginManagerProvider.class), 0);
return pinfo.processName;
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
return "";
}
}