Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
DiDi
virtualapk
提交
4b98b1dd
V
virtualapk
项目概览
DiDi
/
virtualapk
8 个月 前同步成功
通知
63
Star
8886
Fork
1530
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
V
virtualapk
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
4b98b1dd
编写于
7月 20, 2018
作者:
S
superq_sky
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Optimized some code extensibility.
上级
a0fda07c
变更
18
隐藏空白更改
内联
并排
Showing
18 changed file
with
302 addition
and
156 deletion
+302
-156
AndroidStub/src/main/java/android/content/res/Resources.java
AndroidStub/src/main/java/android/content/res/Resources.java
+12
-0
CoreLibrary/src/main/java/android/content/ContentResolverWrapper.java
...src/main/java/android/content/ContentResolverWrapper.java
+2
-1
CoreLibrary/src/main/java/com/didi/virtualapk/PluginManager.java
...rary/src/main/java/com/didi/virtualapk/PluginManager.java
+63
-42
CoreLibrary/src/main/java/com/didi/virtualapk/delegate/ActivityManagerProxy.java
...va/com/didi/virtualapk/delegate/ActivityManagerProxy.java
+1
-2
CoreLibrary/src/main/java/com/didi/virtualapk/delegate/IContentProviderProxy.java
...a/com/didi/virtualapk/delegate/IContentProviderProxy.java
+3
-10
CoreLibrary/src/main/java/com/didi/virtualapk/delegate/LocalService.java
.../main/java/com/didi/virtualapk/delegate/LocalService.java
+1
-1
CoreLibrary/src/main/java/com/didi/virtualapk/delegate/RemoteContentProvider.java
...a/com/didi/virtualapk/delegate/RemoteContentProvider.java
+8
-0
CoreLibrary/src/main/java/com/didi/virtualapk/internal/ActivityLifecycleCallbacksProxy.java
.../virtualapk/internal/ActivityLifecycleCallbacksProxy.java
+104
-0
CoreLibrary/src/main/java/com/didi/virtualapk/internal/LoadedPlugin.java
.../main/java/com/didi/virtualapk/internal/LoadedPlugin.java
+36
-38
CoreLibrary/src/main/java/com/didi/virtualapk/internal/PluginContentResolver.java
...a/com/didi/virtualapk/internal/PluginContentResolver.java
+3
-3
CoreLibrary/src/main/java/com/didi/virtualapk/internal/ResourcesManager.java
...n/java/com/didi/virtualapk/internal/ResourcesManager.java
+18
-16
CoreLibrary/src/main/java/com/didi/virtualapk/internal/VAInstrumentation.java
.../java/com/didi/virtualapk/internal/VAInstrumentation.java
+6
-10
CoreLibrary/src/main/java/com/didi/virtualapk/internal/utils/DexUtil.java
...main/java/com/didi/virtualapk/internal/utils/DexUtil.java
+2
-1
CoreLibrary/src/main/java/com/didi/virtualapk/internal/utils/PackageParserCompat.java
...m/didi/virtualapk/internal/utils/PackageParserCompat.java
+23
-21
CoreLibrary/src/main/java/com/didi/virtualapk/internal/utils/PluginUtil.java
...n/java/com/didi/virtualapk/internal/utils/PluginUtil.java
+4
-3
CoreLibrary/src/main/java/com/didi/virtualapk/internal/utils/Settings.java
...ain/java/com/didi/virtualapk/internal/utils/Settings.java
+1
-1
CoreLibrary/src/main/java/com/didi/virtualapk/utils/RunUtil.java
...rary/src/main/java/com/didi/virtualapk/utils/RunUtil.java
+10
-6
CoreLibrary/src/main/java/com/didi/virtualapk/utils/ZipVerifyUtil.java
...rc/main/java/com/didi/virtualapk/utils/ZipVerifyUtil.java
+5
-1
未找到文件。
AndroidStub/src/main/java/android/content/res/Resources.java
浏览文件 @
4b98b1dd
...
...
@@ -16,6 +16,10 @@ public class Resources {
throw
new
RuntimeException
(
"Stub!"
);
}
public
int
getColor
(
int
id
)
throws
NotFoundException
{
throw
new
RuntimeException
(
"Stub!"
);
}
public
Configuration
getConfiguration
()
{
throw
new
RuntimeException
(
"Stub!"
);
}
...
...
@@ -28,6 +32,10 @@ public class Resources {
throw
new
RuntimeException
(
"Stub!"
);
}
public
String
getString
(
int
id
)
throws
NotFoundException
{
throw
new
RuntimeException
(
"Stub!"
);
}
public
CharSequence
getText
(
int
id
)
throws
NotFoundException
{
throw
new
RuntimeException
(
"Stub!"
);
}
...
...
@@ -44,6 +52,10 @@ public class Resources {
throw
new
RuntimeException
(
"Stub!"
);
}
public
void
updateConfiguration
(
Configuration
config
,
DisplayMetrics
metrics
)
{
throw
new
RuntimeException
(
"Stub!"
);
}
public
final
class
Theme
{
public
void
applyStyle
(
int
resId
,
boolean
force
)
{
...
...
CoreLibrary/src/main/java/android/content/ContentResolverWrapper.java
浏览文件 @
4b98b1dd
...
...
@@ -52,7 +52,8 @@ public abstract class ContentResolverWrapper extends ContentResolver {
@TargetApi
(
Build
.
VERSION_CODES
.
KITKAT_WATCH
)
@Override
public
void
appNotRespondingViaProvider
(
IContentProvider
icp
)
{
mBase
.
appNotRespondingViaProvider
(
icp
);
// dark greylist in Android P
// mBase.appNotRespondingViaProvider(icp);
}
}
CoreLibrary/src/main/java/com/didi/virtualapk/PluginManager.java
浏览文件 @
4b98b1dd
...
...
@@ -31,17 +31,18 @@ import android.content.pm.ProviderInfo;
import
android.content.pm.ResolveInfo
;
import
android.net.Uri
;
import
android.os.Build
;
import
android.os.Bundle
;
import
android.os.Handler
;
import
android.util.Log
;
import
android.util.Singleton
;
import
com.didi.virtualapk.delegate.ActivityManagerProxy
;
import
com.didi.virtualapk.delegate.IContentProviderProxy
;
import
com.didi.virtualapk.delegate.RemoteContentProvider
;
import
com.didi.virtualapk.internal.ComponentsHandler
;
import
com.didi.virtualapk.internal.LoadedPlugin
;
import
com.didi.virtualapk.internal.PluginContentResolver
;
import
com.didi.virtualapk.internal.VAInstrumentation
;
import
com.didi.virtualapk.utils.PluginUtil
;
import
com.didi.virtualapk.
internal.
utils.PluginUtil
;
import
com.didi.virtualapk.utils.Reflector
;
import
com.didi.virtualapk.utils.RunUtil
;
...
...
@@ -66,14 +67,15 @@ public class PluginManager {
private
static
volatile
PluginManager
sInstance
=
null
;
// Context of host app
private
Context
mContext
;
private
ComponentsHandler
mComponentsHandler
;
private
Map
<
String
,
LoadedPlugin
>
mPlugins
=
new
ConcurrentHashMap
<>();
private
final
List
<
Callback
>
mCallbacks
=
new
ArrayList
<>();
protected
final
Context
mContext
;
protected
final
Application
mApplication
;
protected
ComponentsHandler
mComponentsHandler
;
protected
final
Map
<
String
,
LoadedPlugin
>
mPlugins
=
new
ConcurrentHashMap
<>();
protected
final
List
<
Callback
>
mCallbacks
=
new
ArrayList
<>();
pr
ivate
VAInstrumentation
mInstrumentation
;
// Hooked instrumentation
pr
ivate
IActivityManager
mActivityManager
;
// Hooked IActivityManager binder
pr
ivate
IContentProvider
mIContentProvider
;
// Hooked IContentProvider binder
pr
otected
VAInstrumentation
mInstrumentation
;
// Hooked instrumentation
pr
otected
IActivityManager
mActivityManager
;
// Hooked IActivityManager binder
pr
otected
IContentProvider
mIContentProvider
;
// Hooked IContentProvider binder
public
static
PluginManager
getInstance
(
Context
base
)
{
if
(
sInstance
==
null
)
{
...
...
@@ -89,14 +91,22 @@ public class PluginManager {
private
static
PluginManager
createInstance
(
Context
context
)
{
try
{
String
factoryClass
=
context
.
getPackageManager
()
.
getApplicationInfo
(
context
.
getPackageName
(),
PackageManager
.
GET_META_DATA
)
.
metaData
.
getString
(
"VA_FACTORY"
);
Bundle
metaData
=
context
.
getPackageManager
()
.
getApplicationInfo
(
context
.
getPackageName
(),
PackageManager
.
GET_META_DATA
)
.
metaData
;
if
(
metaData
==
null
)
{
return
new
PluginManager
(
context
);
}
String
factoryClass
=
metaData
.
getString
(
"VA_FACTORY"
);
if
(
factoryClass
==
null
)
{
return
new
PluginManager
(
context
);
}
PluginManager
pluginManager
=
Reflector
.
on
(
factoryClass
).
method
(
"create"
,
Context
.
class
).
call
(
context
);
if
(
pluginManager
!=
null
)
{
Log
.
d
(
TAG
,
"Created a instance of "
+
pluginManager
.
getClass
());
return
pluginManager
;
...
...
@@ -110,17 +120,25 @@ public class PluginManager {
}
protected
PluginManager
(
Context
context
)
{
Context
app
=
context
.
getApplicationContext
();
if
(
app
==
null
)
{
this
.
mContext
=
context
;
if
(
context
instanceof
Application
)
{
this
.
mApplication
=
(
Application
)
context
;
this
.
mContext
=
mApplication
.
getBaseContext
()
;
}
else
{
this
.
mContext
=
((
Application
)
app
).
getBaseContext
();
final
Context
app
=
context
.
getApplicationContext
();
if
(
app
==
null
)
{
this
.
mContext
=
context
;
this
.
mApplication
=
ActivityThread
.
currentApplication
();
}
else
{
this
.
mApplication
=
(
Application
)
app
;
this
.
mContext
=
mApplication
.
getBaseContext
();
}
}
prepare
();
mComponentsHandler
=
createComponentsHandler
();
hookCurrentProcess
();
}
private
void
prepare
()
{
mComponentsHandler
=
createComponentsHandler
();
protected
void
hookCurrentProcess
()
{
hookInstrumentationAndHandler
();
hookSystemServices
();
hookDataBindingUtil
();
...
...
@@ -138,6 +156,10 @@ public class PluginManager {
protected
void
doInWorkThread
()
{
}
public
Application
getHostApplication
()
{
return
this
.
mApplication
;
}
protected
ComponentsHandler
createComponentsHandler
()
{
return
new
ComponentsHandler
(
this
);
}
...
...
@@ -208,10 +230,10 @@ public class PluginManager {
try
{
ActivityThread
activityThread
=
ActivityThread
.
currentActivityThread
();
Instrumentation
baseInstrumentation
=
activityThread
.
getInstrumentation
();
if
(
baseInstrumentation
.
getClass
().
getName
().
contains
(
"lbe"
))
{
// reject executing in paralell space, for example, lbe.
System
.
exit
(
0
);
}
//
if (baseInstrumentation.getClass().getName().contains("lbe")) {
//
// reject executing in paralell space, for example, lbe.
//
System.exit(0);
//
}
final
VAInstrumentation
instrumentation
=
createInstrumentation
(
baseInstrumentation
);
...
...
@@ -225,14 +247,14 @@ public class PluginManager {
}
protected
void
hookIContentProviderAsNeeded
()
{
Uri
uri
=
Uri
.
parse
(
PluginContentResolv
er
.
getUri
(
mContext
));
Uri
uri
=
Uri
.
parse
(
RemoteContentProvid
er
.
getUri
(
mContext
));
mContext
.
getContentResolver
().
call
(
uri
,
"wakeup"
,
null
,
null
);
try
{
Field
authority
=
null
;
Field
mP
rovider
=
null
;
Field
p
rovider
=
null
;
ActivityThread
activityThread
=
ActivityThread
.
currentActivityThread
();
Map
mP
roviderMap
=
Reflector
.
with
(
activityThread
).
field
(
"mProviderMap"
).
get
();
Iterator
iter
=
mP
roviderMap
.
entrySet
().
iterator
();
Map
p
roviderMap
=
Reflector
.
with
(
activityThread
).
field
(
"mProviderMap"
).
get
();
Iterator
iter
=
p
roviderMap
.
entrySet
().
iterator
();
while
(
iter
.
hasNext
())
{
Map
.
Entry
entry
=
(
Map
.
Entry
)
iter
.
next
();
Object
key
=
entry
.
getKey
();
...
...
@@ -247,12 +269,12 @@ public class PluginManager {
}
auth
=
(
String
)
authority
.
get
(
key
);
}
if
(
auth
.
equals
(
PluginContentResolv
er
.
getAuthority
(
mContext
)))
{
if
(
mP
rovider
==
null
)
{
mP
rovider
=
val
.
getClass
().
getDeclaredField
(
"mProvider"
);
mP
rovider
.
setAccessible
(
true
);
if
(
auth
.
equals
(
RemoteContentProvid
er
.
getAuthority
(
mContext
)))
{
if
(
p
rovider
==
null
)
{
p
rovider
=
val
.
getClass
().
getDeclaredField
(
"mProvider"
);
p
rovider
.
setAccessible
(
true
);
}
IContentProvider
rawProvider
=
(
IContentProvider
)
mP
rovider
.
get
(
val
);
IContentProvider
rawProvider
=
(
IContentProvider
)
p
rovider
.
get
(
val
);
IContentProvider
proxy
=
IContentProviderProxy
.
newInstance
(
mContext
,
rawProvider
);
mIContentProvider
=
proxy
;
Log
.
d
(
TAG
,
"hookIContentProvider succeed : "
+
mIContentProvider
);
...
...
@@ -281,17 +303,16 @@ public class PluginManager {
}
LoadedPlugin
plugin
=
createLoadedPlugin
(
apk
);
if
(
null
!=
plugin
)
{
this
.
mPlugins
.
put
(
plugin
.
getPackageName
(),
plugin
);
synchronized
(
mCallbacks
)
{
for
(
int
i
=
0
;
i
<
mCallbacks
.
size
();
i
++)
{
mCallbacks
.
get
(
i
).
onAddedLoadedPlugin
(
plugin
);
}
if
(
null
==
plugin
)
{
throw
new
RuntimeException
(
"Can't load plugin which is invalid: "
+
apk
.
getAbsolutePath
());
}
this
.
mPlugins
.
put
(
plugin
.
getPackageName
(),
plugin
);
synchronized
(
mCallbacks
)
{
for
(
int
i
=
0
;
i
<
mCallbacks
.
size
();
i
++)
{
mCallbacks
.
get
(
i
).
onAddedLoadedPlugin
(
plugin
);
}
// try to invoke plugin's application
plugin
.
invokeApplication
();
}
else
{
throw
new
RuntimeException
(
"Can't load plugin which is invalid: "
+
apk
.
getAbsolutePath
());
}
}
...
...
CoreLibrary/src/main/java/com/didi/virtualapk/delegate/ActivityManagerProxy.java
浏览文件 @
4b98b1dd
...
...
@@ -33,11 +33,10 @@ import android.os.ServiceManager;
import
android.util.Log
;
import
com.didi.virtualapk.PluginManager
;
import
com.didi.virtualapk.utils.PluginUtil
;
import
com.didi.virtualapk.
internal.
utils.PluginUtil
;
import
java.lang.reflect.InvocationHandler
;
import
java.lang.reflect.Method
;
import
java.lang.reflect.Proxy
;
/**
* @author johnsonlee
...
...
CoreLibrary/src/main/java/com/didi/virtualapk/delegate/IContentProviderProxy.java
浏览文件 @
4b98b1dd
...
...
@@ -33,8 +33,6 @@ import java.lang.reflect.Method;
import
java.lang.reflect.Proxy
;
import
java.util.Arrays
;
import
static
com
.
didi
.
virtualapk
.
delegate
.
RemoteContentProvider
.
KEY_WRAPPER_URI
;
/**
* Created by renyugang on 16/12/8.
*/
...
...
@@ -84,7 +82,7 @@ public class IContentProviderProxy implements InvocationHandler {
if
(
method
.
getName
().
equals
(
"call"
))
{
bundleInCallMethod
=
getBundleParameter
(
args
);
if
(
bundleInCallMethod
!=
null
)
{
String
uriString
=
bundleInCallMethod
.
getString
(
KEY_WRAPPER_URI
);
String
uriString
=
bundleInCallMethod
.
getString
(
RemoteContentProvider
.
KEY_WRAPPER_URI
);
if
(
uriString
!=
null
)
{
uri
=
Uri
.
parse
(
uriString
);
}
...
...
@@ -100,14 +98,9 @@ public class IContentProviderProxy implements InvocationHandler {
if
(
info
!=
null
)
{
String
pkg
=
info
.
packageName
;
LoadedPlugin
plugin
=
pluginManager
.
getLoadedPlugin
(
pkg
);
String
pluginUri
=
Uri
.
encode
(
uri
.
toString
());
StringBuilder
builder
=
new
StringBuilder
(
PluginContentResolver
.
getUri
(
mContext
));
builder
.
append
(
"/?plugin="
+
plugin
.
getLocation
());
builder
.
append
(
"&pkg="
+
pkg
);
builder
.
append
(
"&uri="
+
pluginUri
);
Uri
wrapperUri
=
Uri
.
parse
(
builder
.
toString
());
Uri
wrapperUri
=
PluginContentResolver
.
wrapperUri
(
plugin
,
uri
);
if
(
method
.
getName
().
equals
(
"call"
))
{
bundleInCallMethod
.
putString
(
KEY_WRAPPER_URI
,
wrapperUri
.
toString
());
bundleInCallMethod
.
putString
(
RemoteContentProvider
.
KEY_WRAPPER_URI
,
wrapperUri
.
toString
());
}
else
{
args
[
index
]
=
wrapperUri
;
}
...
...
CoreLibrary/src/main/java/com/didi/virtualapk/delegate/LocalService.java
浏览文件 @
4b98b1dd
...
...
@@ -32,7 +32,7 @@ import android.util.Log;
import
com.didi.virtualapk.PluginManager
;
import
com.didi.virtualapk.internal.LoadedPlugin
;
import
com.didi.virtualapk.utils.PluginUtil
;
import
com.didi.virtualapk.
internal.
utils.PluginUtil
;
import
com.didi.virtualapk.utils.Reflector
;
import
java.lang.reflect.Method
;
...
...
CoreLibrary/src/main/java/com/didi/virtualapk/delegate/RemoteContentProvider.java
浏览文件 @
4b98b1dd
...
...
@@ -209,4 +209,12 @@ public class RemoteContentProvider extends ContentProvider {
return
null
;
}
public
static
String
getAuthority
(
Context
context
)
{
return
context
.
getPackageName
()
+
".VirtualAPK.Provider"
;
}
public
static
String
getUri
(
Context
context
)
{
return
"content://"
+
getAuthority
(
context
);
}
}
CoreLibrary/src/main/java/com/didi/virtualapk/internal/ActivityLifecycleCallbacksProxy.java
0 → 100644
浏览文件 @
4b98b1dd
package
com.didi.virtualapk.internal
;
import
android.app.Activity
;
import
android.app.ActivityThread
;
import
android.app.Application
;
import
android.os.Bundle
;
import
com.didi.virtualapk.utils.Reflector
;
import
java.util.ArrayList
;
/**
* Created by qiaopu on 2017/8/9.
*/
class
ActivityLifecycleCallbacksProxy
implements
Application
.
ActivityLifecycleCallbacks
{
final
ArrayList
<
Application
.
ActivityLifecycleCallbacks
>
mActivityLifecycleCallbacks
=
Reflector
.
QuietReflector
.
with
(
ActivityThread
.
currentApplication
()).
field
(
"mActivityLifecycleCallbacks"
).
get
();
Object
[]
collectActivityLifecycleCallbacks
()
{
if
(
mActivityLifecycleCallbacks
==
null
)
{
return
null
;
}
Object
[]
callbacks
=
null
;
synchronized
(
mActivityLifecycleCallbacks
)
{
if
(
mActivityLifecycleCallbacks
.
size
()
>
0
)
{
callbacks
=
mActivityLifecycleCallbacks
.
toArray
();
}
}
return
callbacks
;
}
@Override
public
void
onActivityCreated
(
Activity
activity
,
Bundle
savedInstanceState
)
{
Object
[]
callbacks
=
collectActivityLifecycleCallbacks
();
if
(
callbacks
!=
null
)
{
for
(
int
i
=
0
;
i
<
callbacks
.
length
;
i
++)
{
((
Application
.
ActivityLifecycleCallbacks
)
callbacks
[
i
]).
onActivityCreated
(
activity
,
savedInstanceState
);
}
}
}
@Override
public
void
onActivityStarted
(
Activity
activity
)
{
Object
[]
callbacks
=
collectActivityLifecycleCallbacks
();
if
(
callbacks
!=
null
)
{
for
(
int
i
=
0
;
i
<
callbacks
.
length
;
i
++)
{
((
Application
.
ActivityLifecycleCallbacks
)
callbacks
[
i
]).
onActivityStarted
(
activity
);
}
}
}
@Override
public
void
onActivityResumed
(
Activity
activity
)
{
Object
[]
callbacks
=
collectActivityLifecycleCallbacks
();
if
(
callbacks
!=
null
)
{
for
(
int
i
=
0
;
i
<
callbacks
.
length
;
i
++)
{
((
Application
.
ActivityLifecycleCallbacks
)
callbacks
[
i
]).
onActivityResumed
(
activity
);
}
}
}
@Override
public
void
onActivityPaused
(
Activity
activity
)
{
Object
[]
callbacks
=
collectActivityLifecycleCallbacks
();
if
(
callbacks
!=
null
)
{
for
(
int
i
=
0
;
i
<
callbacks
.
length
;
i
++)
{
((
Application
.
ActivityLifecycleCallbacks
)
callbacks
[
i
]).
onActivityPaused
(
activity
);
}
}
}
@Override
public
void
onActivityStopped
(
Activity
activity
)
{
Object
[]
callbacks
=
collectActivityLifecycleCallbacks
();
if
(
callbacks
!=
null
)
{
for
(
int
i
=
0
;
i
<
callbacks
.
length
;
i
++)
{
((
Application
.
ActivityLifecycleCallbacks
)
callbacks
[
i
]).
onActivityStopped
(
activity
);
}
}
}
@Override
public
void
onActivitySaveInstanceState
(
Activity
activity
,
Bundle
outState
)
{
Object
[]
callbacks
=
collectActivityLifecycleCallbacks
();
if
(
callbacks
!=
null
)
{
for
(
int
i
=
0
;
i
<
callbacks
.
length
;
i
++)
{
((
Application
.
ActivityLifecycleCallbacks
)
callbacks
[
i
]).
onActivitySaveInstanceState
(
activity
,
outState
);
}
}
}
@Override
public
void
onActivityDestroyed
(
Activity
activity
)
{
Object
[]
callbacks
=
collectActivityLifecycleCallbacks
();
if
(
callbacks
!=
null
)
{
for
(
int
i
=
0
;
i
<
callbacks
.
length
;
i
++)
{
((
Application
.
ActivityLifecycleCallbacks
)
callbacks
[
i
]).
onActivityDestroyed
(
activity
);
}
}
}
}
CoreLibrary/src/main/java/com/didi/virtualapk/internal/LoadedPlugin.java
浏览文件 @
4b98b1dd
...
...
@@ -47,17 +47,15 @@ import android.content.res.XmlResourceParser;
import
android.graphics.Rect
;
import
android.graphics.drawable.Drawable
;
import
android.os.Build
;
import
android.os.Looper
;
import
android.os.Process
;
import
android.os.UserHandle
;
import
android.support.annotation.NonNull
;
import
android.support.annotation.Nullable
;
import
android.support.annotation.UiThread
;
import
com.didi.virtualapk.PluginManager
;
import
com.didi.virtualapk.utils.DexUtil
;
import
com.didi.virtualapk.utils.PackageParserCompat
;
import
com.didi.virtualapk.utils.PluginUtil
;
import
com.didi.virtualapk.
internal.
utils.DexUtil
;
import
com.didi.virtualapk.
internal.
utils.PackageParserCompat
;
import
com.didi.virtualapk.
internal.
utils.PluginUtil
;
import
com.didi.virtualapk.utils.Reflector
;
import
com.didi.virtualapk.utils.RunUtil
;
...
...
@@ -74,35 +72,30 @@ import dalvik.system.DexClassLoader;
/**
* Created by renyugang on 16/8/9.
*/
public
final
class
LoadedPlugin
{
public
class
LoadedPlugin
{
public
static
final
String
TAG
=
"LoadedPlugin"
;
protected
ClassLoader
createClassLoader
(
Context
context
,
File
apk
,
File
libsDir
,
ClassLoader
parent
)
{
File
dexOutputDir
=
context
.
getDir
(
Constants
.
OPTIMIZE_DIR
,
Context
.
MODE_PRIVATE
);
protected
File
getDir
(
Context
context
,
String
name
)
{
return
context
.
getDir
(
name
,
Context
.
MODE_PRIVATE
);
}
protected
ClassLoader
createClassLoader
(
Context
context
,
File
apk
,
File
libsDir
,
ClassLoader
parent
)
throws
Exception
{
File
dexOutputDir
=
getDir
(
context
,
Constants
.
OPTIMIZE_DIR
);
String
dexOutputPath
=
dexOutputDir
.
getAbsolutePath
();
DexClassLoader
loader
=
new
DexClassLoader
(
apk
.
getAbsolutePath
(),
dexOutputPath
,
libsDir
.
getAbsolutePath
(),
parent
);
if
(
Constants
.
COMBINE_CLASSLOADER
)
{
try
{
DexUtil
.
insertDex
(
loader
,
parent
);
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
DexUtil
.
insertDex
(
loader
,
parent
);
}
return
loader
;
}
protected
AssetManager
createAssetManager
(
Context
context
,
File
apk
)
{
try
{
AssetManager
am
=
AssetManager
.
class
.
newInstance
();
Reflector
.
with
(
am
).
method
(
"addAssetPath"
,
String
.
class
).
call
(
apk
.
getAbsolutePath
());
return
am
;
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
return
null
;
}
protected
AssetManager
createAssetManager
(
Context
context
,
File
apk
)
throws
Exception
{
AssetManager
am
=
AssetManager
.
class
.
newInstance
();
Reflector
.
with
(
am
).
method
(
"addAssetPath"
,
String
.
class
).
call
(
apk
.
getAbsolutePath
());
return
am
;
}
protected
Resources
createResources
(
Context
context
,
String
packageName
,
File
apk
)
throws
Exception
{
...
...
@@ -151,11 +144,7 @@ public final class LoadedPlugin {
protected
Application
mApplication
;
@UiThread
public
LoadedPlugin
(
PluginManager
pluginManager
,
Context
context
,
File
apk
)
throws
Exception
{
if
(
Thread
.
currentThread
()
!=
Looper
.
getMainLooper
().
getThread
())
{
throw
new
RuntimeException
(
"plugin mast be created by UI thread."
);
}
this
.
mPluginManager
=
pluginManager
;
this
.
mHostContext
=
context
;
this
.
mLocation
=
apk
.
getAbsolutePath
();
...
...
@@ -239,6 +228,9 @@ public final class LoadedPlugin {
}
this
.
mReceiverInfos
=
Collections
.
unmodifiableMap
(
receivers
);
this
.
mPackageInfo
.
receivers
=
receivers
.
values
().
toArray
(
new
ActivityInfo
[
receivers
.
size
()]);
// try to invoke plugin's application
invokeApplication
();
}
protected
void
tryToCopyNativeLib
(
File
apk
)
throws
Exception
{
...
...
@@ -289,7 +281,8 @@ public final class LoadedPlugin {
return
mApplication
;
}
public
void
invokeApplication
()
{
public
void
invokeApplication
()
throws
Exception
{
final
Exception
[]
temp
=
new
Exception
[
1
];
// make sure application's callback is run on ui thread.
RunUtil
.
runOnUiThread
(
new
Runnable
()
{
@Override
...
...
@@ -297,9 +290,17 @@ public final class LoadedPlugin {
if
(
mApplication
!=
null
)
{
return
;
}
mApplication
=
makeApplication
(
false
,
mPluginManager
.
getInstrumentation
());
try
{
mApplication
=
makeApplication
(
false
,
mPluginManager
.
getInstrumentation
());
}
catch
(
Exception
e
)
{
temp
[
0
]
=
e
;
}
}
},
true
);
if
(
temp
[
0
]
!=
null
)
{
throw
temp
[
0
];
}
}
public
String
getPackageResourcePath
()
{
...
...
@@ -379,7 +380,7 @@ public final class LoadedPlugin {
Reflector
.
QuietReflector
.
with
(
this
.
mResources
).
field
(
"mThemeResId"
).
set
(
resid
);
}
protected
Application
makeApplication
(
boolean
forceDefaultAppClass
,
Instrumentation
instrumentation
)
{
protected
Application
makeApplication
(
boolean
forceDefaultAppClass
,
Instrumentation
instrumentation
)
throws
Exception
{
if
(
null
!=
this
.
mApplication
)
{
return
this
.
mApplication
;
}
...
...
@@ -388,15 +389,12 @@ public final class LoadedPlugin {
if
(
forceDefaultAppClass
||
null
==
appClass
)
{
appClass
=
"android.app.Application"
;
}
try
{
this
.
mApplication
=
instrumentation
.
newApplication
(
this
.
mClassLoader
,
appClass
,
this
.
getPluginContext
());
instrumentation
.
callApplicationOnCreate
(
this
.
mApplication
);
return
this
.
mApplication
;
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
return
null
;
}
this
.
mApplication
=
instrumentation
.
newApplication
(
this
.
mClassLoader
,
appClass
,
this
.
getPluginContext
());
// inject activityLifecycleCallbacks of the host application
mApplication
.
registerActivityLifecycleCallbacks
(
new
ActivityLifecycleCallbacksProxy
());
instrumentation
.
callApplicationOnCreate
(
this
.
mApplication
);
return
this
.
mApplication
;
}
public
ResolveInfo
resolveActivity
(
Intent
intent
,
int
flags
)
{
...
...
CoreLibrary/src/main/java/com/didi/virtualapk/internal/PluginContentResolver.java
浏览文件 @
4b98b1dd
...
...
@@ -94,7 +94,7 @@ public class PluginContentResolver extends ContentResolverWrapper {
public
static
Uri
wrapperUri
(
LoadedPlugin
loadedPlugin
,
Uri
pluginUri
)
{
String
pkg
=
loadedPlugin
.
getPackageName
();
String
pluginUriString
=
Uri
.
encode
(
pluginUri
.
toString
());
StringBuilder
builder
=
new
StringBuilder
(
PluginContentResolv
er
.
getUri
(
loadedPlugin
.
getHostContext
()));
StringBuilder
builder
=
new
StringBuilder
(
RemoteContentProvid
er
.
getUri
(
loadedPlugin
.
getHostContext
()));
builder
.
append
(
"/?plugin="
+
loadedPlugin
.
getLocation
());
builder
.
append
(
"&pkg="
+
pkg
);
builder
.
append
(
"&uri="
+
pluginUriString
);
...
...
@@ -104,12 +104,12 @@ public class PluginContentResolver extends ContentResolverWrapper {
@Deprecated
public
static
String
getAuthority
(
Context
context
)
{
return
context
.
getPackageName
()
+
".VirtualAPK.Provider"
;
return
RemoteContentProvider
.
getAuthority
(
context
)
;
}
@Deprecated
public
static
String
getUri
(
Context
context
)
{
return
"content://"
+
getAuthority
(
context
);
return
RemoteContentProvider
.
getUri
(
context
);
}
@Keep
...
...
CoreLibrary/src/main/java/com/didi/virtualapk/internal/ResourcesManager.java
浏览文件 @
4b98b1dd
...
...
@@ -61,7 +61,7 @@ class ResourcesManager {
return
resources
;
}
private
static
synchronized
Resources
createResourcesSimple
(
Context
hostContext
,
String
apk
)
throws
Exception
{
private
static
Resources
createResourcesSimple
(
Context
hostContext
,
String
apk
)
throws
Exception
{
Resources
hostResources
=
hostContext
.
getResources
();
Resources
newResources
=
null
;
AssetManager
assetManager
;
...
...
@@ -69,15 +69,24 @@ class ResourcesManager {
if
(
Build
.
VERSION
.
SDK_INT
<
Build
.
VERSION_CODES
.
LOLLIPOP
)
{
assetManager
=
AssetManager
.
class
.
newInstance
();
reflector
.
bind
(
assetManager
);
reflector
.
call
(
hostContext
.
getApplicationInfo
().
sourceDir
);
final
int
cookie1
=
reflector
.
call
(
hostContext
.
getApplicationInfo
().
sourceDir
);;
if
(
cookie1
==
0
)
{
throw
new
RuntimeException
(
"createResources failed, can't addAssetPath for "
+
hostContext
.
getApplicationInfo
().
sourceDir
);
}
}
else
{
assetManager
=
hostResources
.
getAssets
();
reflector
.
bind
(
assetManager
);
}
reflector
.
call
(
apk
);
final
int
cookie2
=
reflector
.
call
(
apk
);
if
(
cookie2
==
0
)
{
throw
new
RuntimeException
(
"createResources failed, can't addAssetPath for "
+
apk
);
}
List
<
LoadedPlugin
>
pluginList
=
PluginManager
.
getInstance
(
hostContext
).
getAllLoadedPlugins
();
for
(
LoadedPlugin
plugin
:
pluginList
)
{
reflector
.
call
(
plugin
.
getLocation
());
final
int
cookie3
=
reflector
.
call
(
plugin
.
getLocation
());
if
(
cookie3
==
0
)
{
throw
new
RuntimeException
(
"createResources failed, can't addAssetPath for "
+
plugin
.
getLocation
());
}
}
if
(
isMiUi
(
hostResources
))
{
newResources
=
MiUiResourcesCompat
.
createResources
(
hostResources
,
assetManager
);
...
...
@@ -111,22 +120,14 @@ class ResourcesManager {
Object
activityThread
=
ActivityThread
.
currentActivityThread
();
Object
resManager
;
if
(
Build
.
VERSION
.
SDK_INT
>=
19
)
{
if
(
Build
.
VERSION
.
SDK_INT
>=
Build
.
VERSION_CODES
.
KITKAT
)
{
resManager
=
android
.
app
.
ResourcesManager
.
getInstance
();
}
else
{
resManager
=
Reflector
.
with
(
activityThread
).
field
(
"mResourcesManager"
).
get
();
}
if
(
Build
.
VERSION
.
SDK_INT
<
24
)
{
Map
<
Object
,
WeakReference
<
Resources
>>
map
=
Reflector
.
with
(
resManager
).
field
(
"mActiveResources"
).
get
();
Object
key
=
map
.
keySet
().
iterator
().
next
();
map
.
put
(
key
,
new
WeakReference
<>(
resources
));
}
else
{
// still hook Android N Resources, even though it's unnecessary, then nobody will be strange.
Map
map
=
Reflector
.
QuietReflector
.
with
(
resManager
).
field
(
"mResourceImpls"
).
get
();
Object
key
=
map
.
keySet
().
iterator
().
next
();
Object
resourcesImpl
=
Reflector
.
QuietReflector
.
with
(
resources
).
field
(
"mResourcesImpl"
).
get
();
map
.
put
(
key
,
new
WeakReference
<>(
resourcesImpl
));
}
Map
<
Object
,
WeakReference
<
Resources
>>
map
=
Reflector
.
with
(
resManager
).
field
(
"mActiveResources"
).
get
();
Object
key
=
map
.
keySet
().
iterator
().
next
();
map
.
put
(
key
,
new
WeakReference
<>(
resources
));
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
...
...
@@ -279,6 +280,7 @@ class ResourcesManager {
private
static
final
class
ResourcesManagerCompatForN
{
@TargetApi
(
Build
.
VERSION_CODES
.
KITKAT
)
public
static
void
resolveResourcesImplMap
(
Map
<
ResourcesKey
,
WeakReference
<
ResourcesImpl
>>
originalMap
,
Map
<
ResourcesKey
,
WeakReference
<
ResourcesImpl
>>
resolvedMap
,
String
baseResDir
,
String
newAssetPath
)
throws
Exception
{
for
(
Map
.
Entry
<
ResourcesKey
,
WeakReference
<
ResourcesImpl
>>
entry
:
originalMap
.
entrySet
())
{
ResourcesKey
key
=
entry
.
getKey
();
...
...
CoreLibrary/src/main/java/com/didi/virtualapk/internal/VAInstrumentation.java
浏览文件 @
4b98b1dd
...
...
@@ -36,7 +36,7 @@ import android.util.Log;
import
com.didi.virtualapk.PluginManager
;
import
com.didi.virtualapk.delegate.StubActivity
;
import
com.didi.virtualapk.utils.PluginUtil
;
import
com.didi.virtualapk.
internal.
utils.PluginUtil
;
import
com.didi.virtualapk.utils.Reflector
;
import
java.lang.ref.WeakReference
;
...
...
@@ -51,11 +51,11 @@ public class VAInstrumentation extends Instrumentation implements Handler.Callba
public
static
final
String
TAG
=
"VAInstrumentation"
;
public
static
final
int
LAUNCH_ACTIVITY
=
100
;
pr
ivate
Instrumentation
mBase
;
pr
otected
Instrumentation
mBase
;
pr
ivate
final
ArrayList
<
WeakReference
<
Activity
>>
mActivities
=
new
ArrayList
<>();
pr
otected
final
ArrayList
<
WeakReference
<
Activity
>>
mActivities
=
new
ArrayList
<>();
PluginManager
mPluginManager
;
protected
PluginManager
mPluginManager
;
public
VAInstrumentation
(
PluginManager
pluginManager
,
Instrumentation
base
)
{
this
.
mPluginManager
=
pluginManager
;
...
...
@@ -130,12 +130,8 @@ public class VAInstrumentation extends Instrumentation implements Handler.Callba
Activity
activity
=
mBase
.
newActivity
(
plugin
.
getClassLoader
(),
targetClassName
,
intent
);
activity
.
setIntent
(
intent
);
try
{
// for 4.1+
Reflector
.
with
(
activity
).
field
(
"mResources"
).
set
(
plugin
.
getResources
());
}
catch
(
Exception
ignored
)
{
// ignored.
}
// for 4.1+
Reflector
.
QuietReflector
.
with
(
activity
).
field
(
"mResources"
).
set
(
plugin
.
getResources
());
return
newActivity
(
activity
);
}
...
...
CoreLibrary/src/main/java/com/didi/virtualapk/utils/DexUtil.java
→
CoreLibrary/src/main/java/com/didi/virtualapk/
internal/
utils/DexUtil.java
浏览文件 @
4b98b1dd
...
...
@@ -14,13 +14,14 @@
* limitations under the License.
*/
package
com.didi.virtualapk.utils
;
package
com.didi.virtualapk.
internal.
utils
;
import
android.app.ActivityThread
;
import
android.content.Context
;
import
android.os.Build
;
import
com.didi.virtualapk.internal.Constants
;
import
com.didi.virtualapk.utils.Reflector
;
import
java.io.File
;
import
java.lang.reflect.Array
;
...
...
CoreLibrary/src/main/java/com/didi/virtualapk/utils/PackageParserCompat.java
→
CoreLibrary/src/main/java/com/didi/virtualapk/
internal/
utils/PackageParserCompat.java
浏览文件 @
4b98b1dd
...
...
@@ -14,12 +14,14 @@
* limitations under the License.
*/
package
com.didi.virtualapk.utils
;
package
com.didi.virtualapk.
internal.
utils
;
import
android.content.Context
;
import
android.content.pm.PackageParser
;
import
android.os.Build
;
import
com.didi.virtualapk.utils.Reflector
;
import
java.io.File
;
/**
...
...
@@ -27,26 +29,30 @@ import java.io.File;
*/
public
final
class
PackageParserCompat
{
public
static
final
PackageParser
.
Package
parsePackage
(
final
Context
context
,
final
File
apk
,
final
int
flags
)
throws
PackageParser
.
PackageParserException
{
if
(
Build
.
VERSION
.
SDK_INT
>=
24
)
{
if
(
Build
.
VERSION
.
PREVIEW_SDK_INT
==
0
)
{
public
static
final
PackageParser
.
Package
parsePackage
(
final
Context
context
,
final
File
apk
,
final
int
flags
)
{
try
{
if
(
Build
.
VERSION
.
SDK_INT
>=
28
||
(
Build
.
VERSION
.
SDK_INT
==
27
&&
Build
.
VERSION
.
PREVIEW_SDK_INT
!=
0
))
{
// Android P Preview
return
PackageParserPPreview
.
parsePackage
(
context
,
apk
,
flags
);
}
else
if
(
Build
.
VERSION
.
SDK_INT
>=
24
)
{
return
PackageParserV24
.
parsePackage
(
context
,
apk
,
flags
);
}
else
if
(
Build
.
VERSION
.
SDK_INT
>=
21
)
{
return
PackageParserLollipop
.
parsePackage
(
context
,
apk
,
flags
);
}
else
{
return
PackageParser
PPreview
.
parsePackage
(
context
,
apk
,
flags
);
return
PackageParser
Legacy
.
parsePackage
(
context
,
apk
,
flags
);
}
}
else
if
(
Build
.
VERSION
.
SDK_INT
>=
21
)
{
return
PackageParserLollipop
.
parsePackage
(
context
,
apk
,
flags
);
}
else
{
return
PackageParserLegacy
.
parsePackage
(
context
,
apk
,
flags
);
}
catch
(
Throwable
e
)
{
throw
new
RuntimeException
(
"error"
,
e
);
}
}
private
static
final
class
PackageParserPPreview
{
static
final
PackageParser
.
Package
parsePackage
(
Context
context
,
File
apk
,
int
flags
)
throws
PackageParser
.
PackageParserException
{
static
final
PackageParser
.
Package
parsePackage
(
Context
context
,
File
apk
,
int
flags
)
throws
Throwable
{
PackageParser
parser
=
new
PackageParser
();
PackageParser
.
Package
pkg
=
parser
.
parsePackage
(
apk
,
flags
);
Reflector
.
QuietReflector
.
with
(
parser
)
Reflector
.
with
(
parser
)
.
method
(
"collectCertificates"
,
PackageParser
.
Package
.
class
,
boolean
.
class
)
.
call
(
pkg
,
false
);
return
pkg
;
...
...
@@ -55,10 +61,10 @@ public final class PackageParserCompat {
private
static
final
class
PackageParserV24
{
static
final
PackageParser
.
Package
parsePackage
(
Context
context
,
File
apk
,
int
flags
)
throws
PackageParser
.
PackageParserException
{
static
final
PackageParser
.
Package
parsePackage
(
Context
context
,
File
apk
,
int
flags
)
throws
Throwable
{
PackageParser
parser
=
new
PackageParser
();
PackageParser
.
Package
pkg
=
parser
.
parsePackage
(
apk
,
flags
);
Reflector
.
QuietReflector
.
with
(
parser
)
Reflector
.
with
(
parser
)
.
method
(
"collectCertificates"
,
PackageParser
.
Package
.
class
,
int
.
class
)
.
call
(
pkg
,
flags
);
return
pkg
;
...
...
@@ -67,14 +73,10 @@ public final class PackageParserCompat {
private
static
final
class
PackageParserLollipop
{
static
final
PackageParser
.
Package
parsePackage
(
final
Context
context
,
final
File
apk
,
final
int
flags
)
throws
PackageParser
.
PackageParserException
{
static
final
PackageParser
.
Package
parsePackage
(
final
Context
context
,
final
File
apk
,
final
int
flags
)
throws
Throwable
{
PackageParser
parser
=
new
PackageParser
();
PackageParser
.
Package
pkg
=
parser
.
parsePackage
(
apk
,
flags
);
try
{
parser
.
collectCertificates
(
pkg
,
flags
);
}
catch
(
Throwable
e
)
{
// ignored
}
parser
.
collectCertificates
(
pkg
,
flags
);
return
pkg
;
}
...
...
@@ -82,10 +84,10 @@ public final class PackageParserCompat {
private
static
final
class
PackageParserLegacy
{
static
final
PackageParser
.
Package
parsePackage
(
Context
context
,
File
apk
,
int
flags
)
{
static
final
PackageParser
.
Package
parsePackage
(
Context
context
,
File
apk
,
int
flags
)
throws
Throwable
{
PackageParser
parser
=
new
PackageParser
(
apk
.
getAbsolutePath
());
PackageParser
.
Package
pkg
=
parser
.
parsePackage
(
apk
,
apk
.
getAbsolutePath
(),
context
.
getResources
().
getDisplayMetrics
(),
flags
);
Reflector
.
QuietReflector
.
with
(
parser
)
Reflector
.
with
(
parser
)
.
method
(
"collectCertificates"
,
PackageParser
.
Package
.
class
,
int
.
class
)
.
call
(
pkg
,
flags
);
return
pkg
;
...
...
CoreLibrary/src/main/java/com/didi/virtualapk/utils/PluginUtil.java
→
CoreLibrary/src/main/java/com/didi/virtualapk/
internal/
utils/PluginUtil.java
浏览文件 @
4b98b1dd
...
...
@@ -14,7 +14,7 @@
* limitations under the License.
*/
package
com.didi.virtualapk.utils
;
package
com.didi.virtualapk.
internal.
utils
;
import
android.app.Activity
;
import
android.content.ComponentName
;
...
...
@@ -34,6 +34,7 @@ import android.util.Log;
import
com.didi.virtualapk.PluginManager
;
import
com.didi.virtualapk.internal.Constants
;
import
com.didi.virtualapk.internal.LoadedPlugin
;
import
com.didi.virtualapk.utils.Reflector
;
import
java.io.BufferedInputStream
;
import
java.io.BufferedOutputStream
;
...
...
@@ -95,7 +96,7 @@ public class PluginUtil {
return
appInfo
.
theme
;
}
return
PluginUtil
.
selectDefaultTheme
(
0
,
Build
.
VERSION
.
SDK_INT
);
return
selectDefaultTheme
(
0
,
Build
.
VERSION
.
SDK_INT
);
}
public
static
int
selectDefaultTheme
(
final
int
curTheme
,
final
int
targetSdkVersion
)
{
...
...
@@ -106,7 +107,7 @@ public class PluginUtil {
android
.
R
.
style
.
Theme_DeviceDefault_Light_DarkActionBar
);
}
p
rivate
static
int
selectSystemTheme
(
final
int
curTheme
,
final
int
targetSdkVersion
,
final
int
orig
,
final
int
holo
,
final
int
dark
,
final
int
deviceDefault
)
{
p
ublic
static
int
selectSystemTheme
(
final
int
curTheme
,
final
int
targetSdkVersion
,
final
int
orig
,
final
int
holo
,
final
int
dark
,
final
int
deviceDefault
)
{
if
(
curTheme
!=
0
)
{
return
curTheme
;
}
...
...
CoreLibrary/src/main/java/com/didi/virtualapk/utils/Settings.java
→
CoreLibrary/src/main/java/com/didi/virtualapk/
internal/
utils/Settings.java
浏览文件 @
4b98b1dd
...
...
@@ -14,7 +14,7 @@
* limitations under the License.
*/
package
com.didi.virtualapk.utils
;
package
com.didi.virtualapk.
internal.
utils
;
import
android.content.Context
;
import
android.content.SharedPreferences
;
...
...
CoreLibrary/src/main/java/com/didi/virtualapk/utils/RunUtil.java
浏览文件 @
4b98b1dd
...
...
@@ -52,7 +52,7 @@ public class RunUtil {
* @param waitUtilDone if set true, the caller thread will wait until the specific runnable finished.
*/
public
static
void
runOnUiThread
(
Runnable
runnable
,
boolean
waitUtilDone
)
{
if
(
Looper
.
myLooper
()
==
Looper
.
getMainLooper
())
{
if
(
Thread
.
currentThread
()
==
Looper
.
getMainLooper
().
getThread
())
{
runnable
.
run
();
return
;
}
...
...
@@ -121,11 +121,15 @@ public class RunUtil {
@Override
public
void
handleMessage
(
Message
msg
)
{
if
(
msg
.
what
==
MESSAGE_RUN_ON_UITHREAD
)
{
Pair
<
Runnable
,
CountDownLatch
>
pair
=
(
Pair
<
Runnable
,
CountDownLatch
>)
msg
.
obj
;
Runnable
runnable
=
pair
.
first
;
runnable
.
run
();
if
(
pair
.
second
!=
null
)
{
pair
.
second
.
countDown
();
Pair
<
Runnable
,
CountDownLatch
>
pair
=
(
Pair
<
Runnable
,
CountDownLatch
>)
msg
.
obj
;
try
{
Runnable
runnable
=
pair
.
first
;
runnable
.
run
();
}
finally
{
if
(
pair
.
second
!=
null
)
{
pair
.
second
.
countDown
();
}
}
}
}
...
...
CoreLibrary/src/main/java/com/didi/virtualapk/utils/ZipVerifyUtil.java
浏览文件 @
4b98b1dd
...
...
@@ -46,9 +46,13 @@ import java.util.zip.ZipFile;
public
class
ZipVerifyUtil
{
public
static
boolean
verifyZip
(
Context
context
,
String
zipPath
)
{
return
verifyZip
(
context
,
zipPath
,
"test.cer"
);
}
public
static
boolean
verifyZip
(
Context
context
,
String
zipPath
,
String
cerName
)
{
try
{
CertificateFactory
certificateFactory
=
CertificateFactory
.
getInstance
(
"X.509"
);
InputStream
in
=
context
.
getAssets
().
open
(
"test.cer"
);
InputStream
in
=
context
.
getAssets
().
open
(
cerName
);
Certificate
certificate
=
certificateFactory
.
generateCertificate
(
in
);
in
.
close
();
return
verifyZip
(
zipPath
,
certificate
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录