diff --git a/CHINESE.md b/CHINESE.md
deleted file mode 100644
index 3b8e41ede..000000000
--- a/CHINESE.md
+++ /dev/null
@@ -1,95 +0,0 @@
-[](https://github.com/asLody/VirtualApp)
-
-简介
----
-**VirtualApp**是一个**App虚拟化引擎**(简称`VA`)。
-
-**VirtualApp已兼容Android 0(8.0 Preview)。**
-
-VirtualApp在你的App内创建一个`虚拟空间`,你可以在虚拟空间内任意的`安装`、`启动`和`卸载`APK,这一切都与外部隔离,如同一个`沙盒`。
-
-运行在`VA`中的APK无需在外部安装,即VA支持**免安装运行APK**。
-
-VA目前被广泛应用于双开/多开、应用市场、模拟定位、一键改机、隐私保护、游戏修改、自动化测试、无感知热更新等技术领域,但它决不仅限于此,Android本身就是一个极其开放的平台,免安装运行APK这一Feature打开了无限可能--------这都取决于您的想象力。
-
-申明
----
-当您需要将VirtualApp用于**商业用途**时,请务必联系QQ:10890 购买商业授权。您如果未经授权将VirtualApp的App模块作为您自己的App用于牟利或上传软件市场,我们取证后将直接报警(侵犯著作权罪)。购买商业授权是对我们最大的支持和认可,我们将投入更多精力和时间来不断完善优化VirtualApp,作为购买商业授权的回报,您可以获得未开放的商业版本和1vs1的支持(技术、运营、预警)!同时我们也支持基于VirtualApp的APP订制开发,请联系:QQ:10890 洽谈。
-
-请注意
------
-VirtualApp代码的更新频率非常快(`以小时为单位`),每一次代码的更新都有可能修复重大BUG,所以请 `watch` 本项目,并注意随时更新代码,以免给您带来损失!
-
-
-已支持的加固(不断更新)
-----------
-* 360加固
-* 腾讯加固
-* 梆梆加固
-* 梆梆企业版(12306客户端 Pass)
-* 爱加密
-* 百度加固
-* 娜迦加固
-* 乐变加固
-* 网易易盾
-* 通付盾
-* (已支持的加固均可通过VA来脱壳,本技术不公开)
-
-
-在VA使用Google服务
------------
-VA支持运行官方的Google服务套件,同时我们也提供了对`MicroG`的支持。
-
-您可以通过在VA中安装`MicroG`来支持`Google服务`,
-
-这样,即使外部没有Google服务,用户也可以在VA中享受Google服务。
-
-MicroG套件可在此下载:[Download MicroG](https://microg.org/download.html)
-
-MicroG的必要模块:
-* Services Core
-* Services Framework Proxy
-* Store
-
-如果您需要在VA中使用官方的Google服务套件(外部已安装的前提下),
-
-则可以通过 `GmsSupport.installGms(userId)` 来安装。
-
-##### 注意,您不能同时安装MicroGms和官方的Gms。
-
-
-使用说明
-----------
-
-**前往你的Application并添加如下代码:**
-```java
- @Override
- protected void attachBaseContext(Context base) {
- super.attachBaseContext(base);
- try {
- VirtualCore.getCore().startup(base);
- } catch (Throwable e) {
- e.printStackTrace();
- }
- }
-```
-**安装App:**
-```java
- VirtualCore.getCore().installApp({APK PATH}, flags);
-```
-**启动App:**
-```java
- VirtualCore.getCore().launchApp({PackageName});
-```
-**移除App:**
-```java
- VirtualCore.getCore().uninstallApp({PackageName});
-```
-**该App的基本信息:**
-```java
- VirtualCore.getCore().findApp({PackageName});
-```
-
-技术支持
-------------
-QQ群:598536
diff --git a/README.md b/README.md
index e96791aac..a2f30d7ec 100644
--- a/README.md
+++ b/README.md
@@ -1,76 +1,1237 @@
-[](https://github.com/asLody/VirtualApp)
-
-[中国人猛戳这里](CHINESE.md "中文")
-
-About
------
-**VirtualApp** is an open platform for Android that allows you to create a `Virtual Space`,
-you can install and run apk inside. Beyond that, VirtualApp is also a `Plugin Framework`,
-the plugins running on VirtualApp does not require any constraints.
-VirtualApp does **not** require root, it is running on the `local process`.
-
-NOTICE
--------
-**This project has been authorized by the business.**
-
-**You are not allowed to modify the app module and put to the software market, if you do that, The consequences you know :)**
-
-**VirtualApp is not free, If you need to use the lib code, please send email to me :)**
-
-Background
-----------
-
-VirtualApp was born in early 2015, Originally, it is just a simple plugin framework,
-But as time goes on,
-the compatibility of it is getting better and better.
-in the end, it evolved into a `Virtual Container`.
-
-
-Get started
------------
-If you use latest android studio (version 2.0 or above), please disable `Instant Run`.
-Open `Setting | Build,Exception,Deployment`, and disable `Enable Instant Run to hot swap...`
-
-**Goto your Application and insert the following code:**
-```java
- @Override
- protected void attachBaseContext(Context base) {
- super.attachBaseContext(base);
- try {
- VirtualCore.get().startup(base);
- } catch (Throwable e) {
- e.printStackTrace();
- }
- }
-```
-
-**Install a virtual App:**
-```java
- VirtualCore.get().installPackage({APK PATH}, flags);
-
-```
-
-**Launch a virtual App:**
-```java
- //VirtualApp support multi-user-mode which can run multiple instances of a same app.
- //if you don't need this feature, just set `{userId}` to 0.
- Intent intent = VirtualCore.get().getLaunchIntent({PackageName}, {userId});
- VActivityManager.get().startActivity(intent, {userId});
-```
-
-**Uninstall a virtual App:**
-```java
- VirtualCore.get().uninstallPackage({PackageName});
-```
-
-More details, please read the source code of demo app, :-)
-
-Documentation
--------------
-
-VirtualApp currently has **no documentation**, If you are interested in VirtualApp, please send email to me.
-
-About Author
-------------
-
- Lody (imlody@foxmail.com)
+
+[English Doc](README_eng.md "English")
+
+
+
+## What is VA? ##
+VirtualAPP (abbreviation: VA) is a sandbox product running on Android system, which can be understood as a lightweight "Android virtual machine". Its product form is a highly extensible, customizable, integrated SDK that allows you to develop a variety of seemingly impossible projects based on or using VA. Now, VA is widely used in many technology fields as following: mini game collection, blockchain, cloud control, silent hot fix and so on. On the one hand, you can realize cloud control mobile office security and achieve military and government data isolation with VA. On the other hand, you can implement script automation, device-info-mock, and plug-in development. Meanwhile, you can realize multi space and games booster. You can also rent the mobile game account and use the mobile controller without activation by VA. **The code on Github has stopped updating in December 2017. The code of business version is continuously being updated. If you need license to obtain the latest code, please contact WeChat: 10890.**
+
+
+## Terminology in VA ##
+Terminology | Explanation
+---- | ---
+Host | The APP that integrates the VirtualAPP SDK is called host.
+Host Plug-in | A host package is used to run another ABI on the same device. It also called plug-in package,extension package, host plug-in package, host extension package.
+Virtual APP / VAPP | App installed in the VA space
+External APP | App installed in the device
+
+
+## VA Technical architecture ##
+
+VA technology involves the APP layer, Framework layer and Native layer of Android in total.
+App must be installed on the system before it can run. The APP installed inside the VA space is not actually installed into the system, so it cannot run. Then how to get it to run?
+Answer: The only way to do this is to "cheat" the system into thinking it has been installed. This "cheat" process is the core work of the VA Framework, and is also the core technical principle of the VA.
+
+**Here is the description of what did each layer do:**
+
+Layer | Main work
+---- | ---
+VA Space | An internal space is provided by the VA for the installation of the APP to be run inside it, and this space is system isolated.
+VA Framework | This layer is mainly a proxy for Android Framework and VAPP, which is the core of VA. And VA provides a set of VA Framework of its own, which is between Android Framework and VA APP. 1. For VAPP, all the system services it accesses have been proxied by VA Framework, which will modify the request parameters of VAPP and send all the parameters related to VAPP installation information to Android Framework after changing them to the parameters of the host (Some of the requests will be sent to their own VA Server to be processed directly, and no longer send to the Android system). This way Android Framework receives the VAPP request and checks the parameters, and it will think there is no problem.2. When the Android system finishes processing the request and returns the result, the VA Framework will also intercept the return result and restore all the parameters that have been original modified to those that were sent during the VAPP request. This way the interaction between VAPP and Android system can work.
+VA Native | The main purpose of this layer is to accomplish 2 tasks: IO redirection and the request modification for VA APP to interact with Android system. 1. IO redirection is some APPs may be accessed through the hard code absolute path. But if the APP is not installed to the system, this path does not exist. Through IO redirection, it will be redirected to the path to install inside VA.2. In addition, there are some jni functions that cannot be hooked in VA Framework, so they need to be hooked in the native layer.
+
+
+In summary:
+As you can see from the above technical architecture, the internal VA APP actually runs on top of VA's own VA Framework. VA has intercepted all system requests from its internal APP, and through this technology it can also have full control over the APP, not just the multi space. And for the convenience of developers, VA also provides SDK and Hook SDK.
+
+
+## VA Process architecture#
+
+There are five types of processes in the VA’s runtime: CHILD process, VA Host Main process, VA Host Plugin process, VAPP Client process, and VAServer process.
+To support both 32-bit and 64-bit APPs, VA needs to install two packages: a master package and a plug-in package ( In this document, the main package is 32 bits and the plug-in package is 64 bit ).
+Two packages are also necessary because a package can only run in one mode, either 32-bit or 64-bit. So for 32-bit APPs, VA uses the 32-bit main package to run, and for 64-bit APPs, VA uses the 64-bit plug-in package to run.
+The main package contains all the code of VA, and the plug-in package contains only one piece of code that loads the main package code for execution, no other code. So plug-in package rarely needs to be updated, just the main package.
+In addition, whether the main package is chosen to use 32-bit or 64-bit can be modified in the configuration file ( For example, for users who want to access GooglePlay, it will be modified to 64-bit for the main package and 32-bit for the plug-in package ).
+
+**The functions and explanations of the each type of process are as follows:**
+
+Process Type | Function
+---- | ---
+CHILD | Other processes integrated by VA Host, such as: keepalive process, push process, etc.
+VA Host Main | The process where the UI main interface of the VA main package is located. The default main package is 32-bit and the plug-in package is 64-bit, which can be modified and switched in the configuration file
+VA Host Plugin | The process that supports the plug-in package of 64-bit APP. The default main package is 32-bit and the plug-in package is 64-bit, which can be modified and switched in the configuration file.
+VAPP Client | The process generated by the APP installed into VA after it starts, it will modify io.busniess.va:pxxx process name to the real process name of VAPP when it runs.
+VAServer | The process where the VA Server is located, it is used to handle requests in VA that are not assigned to the system for processing, such as APP installation processing.
+
+
+## VA can satisfy almost all your needs ##
+Through the above technical architecture, we can know that VA can fully control APP and provide Hook SDK, which can satisfy almost all your needs in various fields:
+
+1. Satisfy the need of **dual/multi space**
+VA allows you to install multiple WeChat/QQ/WhatsAPP/Facebook and other APPs on the same mobile phone, so you can have one phone with multiple accounts logged in at the same time.
+
+2. Satisfy the need of **mobile security**
+VA provides a set of internal and external isolation mechanisms, including but not limited to (file isolation / component isolation / process communication isolation). Simply speaking, VA internal is a "completely independent space".
+Through VA, work affairs and personal affairs can be safely separated without mutual interference. With a little customization, you can achieve mobile security-related needs such as application behavior audit, data encryption, data acquisition, data leakage prevention, anti-attack leaks and so on.
+ **2.1 Application behavior audit**
+The HOOK capability provided by VA can realize real-time monitoring of user usage behavior and upload violation information to the server. And it's easy to implement things like Time Fence ( whether a feature of the APP can be used in a certain time ), Geo Fence ( whether a feature of the APP can be used in a certain area ), sensitive keyword filtering interception and other functional requirements.
+ **2.2 Data encryption**
+The HOOK capability provided by VA can realize all data/file encryption of the application, ensuring data/file landing security.
+ **2.3 Data acquisition**
+The HOOK capability provided by VA can realize the demand for real-time silent upload of application data, such as chat records and transfer records, preventing them from being deleted afterwards without traceability.
+ **2.4 Data leakage prevention**
+The HOOK capability provided by VA can realize application anti-copy/paste, anti-screenshot/recording, anti-sharing/forwarding, watermark traceability and other requirements.
+ **2.5 Anti-attack leaks**
+With the application control capability provided by VA, privacy-related behaviors such as SMS/ address book/call log/ background recording/background photo/ browsing history and location information can be completely controlled in sandbox, prevent Trojan horses/malicious APPs from acquiring users' real private data, causing serious consequences such as leakage of secrets.
+3. Satisfy the need of **ROOT without HOOK**
+VA provides Hook capability of Java and Native. With VA, you can easily achieve functions required by various scenarios, such as virtual positioning, changing device, APP monitoring and management, mobile security and so on.
+
+4. Satisfy the need of **silent installation**
+VA provides the ability to silently install, silently upgrade and silently uninstall APPs. For example, the application store or game center can be integrated with VA to avoid the need for users to manually click to confirm the installation operation, so that it can be installed into VA immediately after downloading, bringing users an experience like "small program" , completely avoiding the problem of applications not easily installed by users.
+
+5. Satisfy the need of **APP controlled**
+You can clearly grasp the system API, sensitive data, device information, etc. accessed by the APP through VA. For example, whether the APP accesses the contacts, photo albums, call log, whether it accesses the user's geographic location and other information.
+Of course, you can also control or construct custom messages to these APPs via VA, and not only that, you can also get access to the APP's private data, such as chat database and so on. In a word, through the application control capability provided by VA, you can easily control all the behaviors of the APP, even modify the content of the APP and server interaction and so on .
+
+
+6. Satisfy the need of **overseas markets**
+VA implements support for Google services to support overseas APPs running, such as Twitter, Messenger, WhatsAPP, Instagram, FaceBook, Youtube and so on.
+
+7. Satisfy the need of **almost everything you can think of**
+VA has complete oversight and control over the internal APP, and can meet almost any of your needs!
+8. VA is also the only commercially licensed product in this technology area
+**Hundreds of** licensed customers are currently paying to use the business version of VirtualAPP code, and the APP integrated with VirtualAPP code is launched more than 200 million times per day. Many Android engineers provide us with user feedback in different scenarios, and through our technical team's continuous optimization and iteration, we continue to improve product performance and compatibility.
+
+
+VA Specialized capabilities
+---
+
+- Cloning ability
+You can clone the APP already installed in the external system and run it internally without mutual interference. Typical application scenario is double space.
+
+- Without installation ability
+In addition to cloning already installed, VA can install (externally silent ) apk's directly internally and run them directly internally. Typical application scenarios are plug-in, standalone APP marketplace and so on.
+
+- Double space ability
+VA is not only "double space", but also has a unique multi-user mode that allows users to open the same APP internally for an unlimited number of times.
+
+- Internal and external isolation ability
+VA is a standard sandbox, or "virtual machine", that provides a set of internal and external isolation mechanisms, including but not limited to (file isolation/component isolation/process communication isolation). Simply put, the inside of a VA is a "completely separate space". Simply put, the inside of a VA is a "completely separate space". Based on it, you can realize a "virtual phone" on your cell phone with a little customization. Of course, you can also use your imagination to customize it for data encryption, data isolation, privacy protection, and enterprise management applications.
+
+- Full control over internal APPs ability
+VA has complete monitoring and control over the internal APP, which is absolutely impossible to achieve in an external environment without Root.
+
+
+Details(Drop down to open)
+ 1. Service request control. First, VA directly provides some service request interception, you can easily customize these service requests when integrating VA, including but far from limited to (APP request to install apk / APP request to open certain files / APP request for location data / APP request for phone information, etc.)
+ 2. System API control. VA virtualizes and implements the entire Android system framework, which is the principle that VA can run apk internally without installation. And you can through modify the virtual framework's implementation to dynamically monitor and analyze the behavior of the app, etc. In addition, you can also mock some system behavior to achieve some needs that are difficult to achieve externally (e.g. game controller).
+ 3. Memory read and write. VA can read and write the memory of internal APP processes without Root.
+ 4. Root without debugging. VA can debug (ptrace) internal APP processes without Root, based on which you can also achieve Root-free process injection.
+ 5. Load arbitrary "plug-in" and "behaviors". The APP process inside VA is derived from the Client side code of the VA framework, so you can insert any "load" and "control" logic into the entry code of the process. These are very simple to implement.
+ 6. Hook. VA has a set of built-in Xposed framework and native hook framework running on all versions of Android (until AndroidQ), based on it, you can easily Hook any Java/Native of any internal APP.
+ 7. File control. VA built in a complete file redirection, which allows easy control of reading and writing of files from internal apps. Based on it, you can realize many functions such as protection and encryption of files can be achieved.
+ 8. Note: The above control capabilities are implemented with code or examples for reference.
+
+
+
+VA Other features
+---
+
+- High performance
+Process-level "virtual machine", VA's unique implementation model makes its performance almost the same as that of the native APP, and does not need a long startup of ordinary virtual machines.
+
+- Full version support
+Support 5.0-16.0, 32-bit/64-bit APP, ARM and X86 processor. And support Android version in the future which will be updated.
+
+- Easy Expansion and Integration
+The integration of VA is similar to the normal Android library, even if your APP has been online, you can conveniently integrate VA and enjoy the capability brought by VA.
+
+- Support Google services
+Provide support for Google services in order to support overseas APPs.
+
+
+## Comparison between VA and other technical solutions ##
+When doing enterprise-level mobile security, it is often necessary to control the APP, and the following is a comparison of possible technical solutions listed:
+
+Technical solution | Principle introduction | Comment | Running performance | Compatibility stability | Project maintenance cost
+---- | --- | --- | --- | --- | ---
+Repackage | Repackage the target APP by decompiling it and adding your own control code | 1. Nowadays, almost all APPs have hardened or tamper-proof protection, and repackaging is already a very difficult task 2.The mobile phone system will also detect whether the APP is repackaged, if it is repackaged, it will directly prompt the user that there is a security risk, and even not allow the installation3.For each APP, even each version to go deep to reverse analysis, time-consuming and difficult to maintain | Excellent | Poor | High
+Custom ROM | By customizing the system source code and compiling it to flash to the designated mobile phone | Only for specified internal mobile phones, too limited to be extended | Excellent | Excellent | High
+ROOT the mobile phone | By rooting the mobile phone,flashing a framework which is similar to Xposed | 1.Now, root the mobile phone is an unlikely thing 2.In reality, it is difficult for users to root their own mobile phones | Excellent | Poor | High
+VA | Lightweight virtual machine with high speed and low device requirements | No risk point mentioned above | Excellent | Excellent. Hundreds of companies testing feedback at the same time | Low.
+VA provides API and a professional technical team to ensure the stable operation of the project
+
+As you can see from the above comparison, VA is an excellent product and can reduce your development and maintenance costs.
+
+## Integrating VA Steps ##
+Step 1: Call the VA interface```VirtualCore.get().startup()```in your application to start the VA engine.
+Step 2: Call VA interface```VirtualCore.get().installPackageAsUser(userId, packageName)```to install the target APP into VA.
+Step 3: Call VA interface```VActivityManager.get().launchApp(userId, packageName)```to start the APP.
+**With only the above 3 APIs to complete the basic use, VA has shielded the complex technical details and provided the interface API to make your development easy.**
+
+## VA compatible stability ##
+VA has been extensively tested by ** hundreds of **companies, including **high standards of testing and feedback of dozens of listed companies**, covering almost all types of equipment and scenarios at home and abroad, providing full protection for your stable operation!
+
+
+Up to now, the supported system versions:
+
+System version | Whether to support
+---- | ---
+5.0 | support
+5.1 | support
+6.0 | support
+7.0 | support
+8.0 | support
+9.1 | support
+10.0 | support
+11.0 | support
+12.0 | support
+13.0 | support
+14.0 | support
+15.0 | support
+16.0 | support
+
+
+
+Supported App Types:
+
+App Type | Whether to support
+---- | ---
+32-bit APP | support
+64-bit APP | support
+
+
+Supported HOOK Types:
+
+Hook Type | Whether to support
+---- | ---
+Java Hook | support
+Native Hook | support
+
+Supported CPU Types:
+
+Hook Type | Whether to support
+---- | ---
+ARM 32 | support
+ARM 64 | support
+
+
+## How to give feedback on problems encountered with integrated VA ? ##
+After the purchase of the license we will establish a WeChat group, any problems can always feedback to us, and according to the priority in the first time to deal with.
+
+## VA Development document ##
+Please refer to the VA development documentation:[Development document](doc/VADev_eng.md)
+
+
+License Instructions
+------
+VirtualApp virtual machine technology belongs to: Jining Luohe Network Technology Co., LTD. It applied for several VirtualApp intellectual property rights from 2015 to 2026 and` is protected by the Intellectual property Law of the People's Republic of China`.When you need to use the code on Github, **please purchase a business license**,and receive the full source code of the latest VirtualApp business version.Hundreds of licensed customers are paying to use the business version of VirtualApp code, and the app integrated with VirtualApp code is launched more than 200 million times a day. Many Android engineers provided us with user feedback in different scenarios, and through our technical team's continuous optimization and iteration, VirtualApp Business Edition code has better performance and higher compatibility. `The company of that year will become one of them after obtaining the license, and enjoy the technological achievements after the continuous iteration. And we can interact and collaborate with our licensed customers operationally, technically and commercially.`
+
+
+Person in charge: Mr. Zhang
+WeChat:10890
+
+
+
+Serious statement
+------
+If you use VirtualApp for **internal use, business profit or upload it to the application market**without licensing. We will take evidence and then report you to the police (for copyright infringement) or prosecute you. It will cause your company to undertake criminal liability and legal action, and affect your company's goodwill and investment.`Purchasing a business license can save you a lot of time developing, testing and refining compatibility, leaving you more time for innovation and profitability.`Luo He Technology has called to the police and sued a number of individuals and companies in 2020.
+
+**In response to the national call for the protection of intellectual property rights! Anyone who reports that his or her company or other companies are using VirtualApp code to develop products without licensing will be given a cash reward upon verification. We will keep the identity of the whistleblower confidential! Reporting WeChat: 10890.**
+
+
+
+Major updates of the business version
+------
+
+1. Support Android 16.0
+2. Support Seccomp-Bpf.
+3. Not easily misreported by anti-virus software
+4. Framework optimization, performance greatly improved
+5. Mobile system and APP compatibility greatly improved
+6. Run Google services perfectly
+7. Supports running pure 64-bit Apps
+8. Built-in `XPosed Hook` framework
+9. Add positioning mock code
+10. Add code to change device
+11. Nearly 700 other fixes and improvements
+
+
+
+
+
+
+
+
+
+
diff --git a/VirtualApp/app/build.gradle b/VirtualApp/app/build.gradle
index acee148a4..6fee2f9fe 100644
--- a/VirtualApp/app/build.gradle
+++ b/VirtualApp/app/build.gradle
@@ -1,10 +1,9 @@
apply plugin: 'com.android.application'
-apply plugin: 'me.tatarka.retrolambda'
android {
- compileSdkVersion 25
- buildToolsVersion "25.0.2"
+ compileSdkVersion 26
+ buildToolsVersion '26.0.2'
defaultConfig {
applicationId "io.virtualapp"
minSdkVersion 15
@@ -53,13 +52,13 @@ dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
compile project(':lib')
//Android Lib
- compile 'com.android.support:multidex:1.0.1'
- compile 'com.android.support:appcompat-v7:25.0.1'
+ compile 'com.android.support:multidex:1.0.2'
+ compile 'com.android.support:appcompat-v7:25.4.0'
compile 'com.melnykov:floatingactionbutton:1.3.0'
- compile 'com.android.support:recyclerview-v7:25.0.1'
- compile 'com.android.support:percent:25.0.1'
- compile 'com.android.support:design:25.0.1'
- compile 'com.android.support:cardview-v7:25.0.1'
+ compile 'com.android.support:recyclerview-v7:25.4.0'
+ compile 'com.android.support:percent:25.4.0'
+ compile 'com.android.support:design:25.4.0'
+ compile 'com.android.support:cardview-v7:25.4.0'
//Promise Support
compile 'org.jdeferred:jdeferred-android-aar:1.2.4'
// ThirdParty
diff --git a/VirtualApp/app/src/main/res/values-zh-rTW/strings.xml b/VirtualApp/app/src/main/res/values-zh-rTW/strings.xml
new file mode 100644
index 000000000..84b69e6f8
--- /dev/null
+++ b/VirtualApp/app/src/main/res/values-zh-rTW/strings.xml
@@ -0,0 +1,24 @@
+
+ VirtualApp
+ 桌面
+ 新增App
+ 正在打開App,請稍候…
+ 刪除
+ 建立捷徑
+ 新的用戶
+ 開啟
+ 儲存
+ 儲存成功!
+ 製造商
+ 請稍候…
+ 品牌
+ 機型
+ 偽造裝置資訊
+ Wifi狀態
+ 配置裝置資訊
+ 關於
+ 克隆App
+ 外部空間
+ 安裝 (%d)
+ 不能一次性安裝超過 9 個程式!
+
diff --git a/VirtualApp/build.gradle b/VirtualApp/build.gradle
index 7aa701d03..cc3fc8ce5 100644
--- a/VirtualApp/build.gradle
+++ b/VirtualApp/build.gradle
@@ -3,11 +3,14 @@
buildscript {
repositories {
jcenter()
+ maven {
+ url 'https://maven.google.com/'
+ name 'Google'
+ }
}
dependencies {
- classpath 'com.android.tools.build:gradle:2.3.1'
- classpath 'me.tatarka:gradle-retrolambda:3.6.0'
- classpath 'com.android.tools.build:gradle-experimental:0.8.0'
+ classpath 'com.android.tools.build:gradle:3.0.1'
+ classpath 'com.android.tools.build:gradle-experimental:0.11.0'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
@@ -19,6 +22,10 @@ allprojects {
maven {
url "https://jitpack.io"
}
+ maven {
+ url 'https://maven.google.com/'
+ name 'Google'
+ }
}
}
diff --git a/VirtualApp/gradle/wrapper/gradle-wrapper.properties b/VirtualApp/gradle/wrapper/gradle-wrapper.properties
index 00a91bd00..074ca5298 100644
--- a/VirtualApp/gradle/wrapper/gradle-wrapper.properties
+++ b/VirtualApp/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
-#Sun Jan 15 17:29:32 CST 2017
+#Sun Nov 19 13:36:42 CST 2017
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip
diff --git a/VirtualApp/lib/build.gradle b/VirtualApp/lib/build.gradle
index d0dd7fa60..6008db59a 100644
--- a/VirtualApp/lib/build.gradle
+++ b/VirtualApp/lib/build.gradle
@@ -1,8 +1,8 @@
apply plugin: 'com.android.library'
android {
- compileSdkVersion 24
- buildToolsVersion "25.0.2"
+ compileSdkVersion 26
+ buildToolsVersion '26.0.2'
defaultConfig {
minSdkVersion 14
@@ -11,7 +11,7 @@ android {
versionName "1.0"
externalNativeBuild {
ndkBuild {
- abiFilters "armeabi", "armeabi-v7a"
+ abiFilters "armeabi-v7a", "x86"
}
}
}
diff --git a/VirtualApp/lib/src/main/aidl/com/lody/virtual/server/IAccountManager.aidl b/VirtualApp/lib/src/main/aidl/com/lody/virtual/server/IAccountManager.aidl
deleted file mode 100644
index 0847ff426..000000000
--- a/VirtualApp/lib/src/main/aidl/com/lody/virtual/server/IAccountManager.aidl
+++ /dev/null
@@ -1,47 +0,0 @@
-package com.lody.virtual.server;
-
-import android.accounts.IAccountManagerResponse;
-import android.accounts.Account;
-import android.accounts.AuthenticatorDescription;
-import android.os.Bundle;
-
-
-/**
- * Central application service that provides account management.
- * @hide
- */
-interface IAccountManager {
- AuthenticatorDescription[] getAuthenticatorTypes(int userId);
- void getAccountsByFeatures(int userId, in IAccountManagerResponse response, in String type, in String[] features);
- String getPreviousName(int userId, in Account account);
- Account[] getAccounts(int userId, in String type);
- void getAuthToken(int userId, in IAccountManagerResponse response, in Account account, in String authTokenType, in boolean notifyOnAuthFailure, in boolean expectActivityLaunch, in Bundle loginOptions);
- void setPassword(int userId, in Account account, in String password);
- void setAuthToken(int userId, in Account account, in String authTokenType, in String authToken);
- void setUserData(int userId, in Account account, in String key, in String value);
- void hasFeatures(int userId, in IAccountManagerResponse response,
- in Account account, in String[] features);
- void updateCredentials(int userId, in IAccountManagerResponse response, in Account account,
- in String authTokenType, in boolean expectActivityLaunch,
- in Bundle loginOptions);
- void editProperties(int userId, in IAccountManagerResponse response, in String accountType,
- in boolean expectActivityLaunch);
- void getAuthTokenLabel(int userId, in IAccountManagerResponse response, in String accountType,
- in String authTokenType);
- String getUserData(int userId, in Account account, in String key);
- String getPassword(int userId, in Account account);
- void confirmCredentials(int userId, in IAccountManagerResponse response, in Account account, in Bundle options, in boolean expectActivityLaunch);
- void addAccount(int userId, in IAccountManagerResponse response, in String accountType,
- in String authTokenType, in String[] requiredFeatures,
- in boolean expectActivityLaunch, in Bundle optionsIn);
- boolean addAccountExplicitly(int userId, in Account account, in String password, in Bundle extras);
- boolean removeAccountExplicitly(int userId, in Account account);
- void renameAccount(int userId, in IAccountManagerResponse response, in Account accountToRename, in String newName);
- void removeAccount(in int userId, in IAccountManagerResponse response, in Account account,
- in boolean expectActivityLaunch);
- void clearPassword(int userId, in Account account);
- boolean accountAuthenticated(int userId, in Account account);
- void invalidateAuthToken(int userId, in String accountType, in String authToken);
- String peekAuthToken(int userId, in Account account, in String authTokenType);
-
-}
\ No newline at end of file
diff --git a/VirtualApp/lib/src/main/aidl/com/lody/virtual/server/IActivityManager.aidl b/VirtualApp/lib/src/main/aidl/com/lody/virtual/server/IActivityManager.aidl
deleted file mode 100644
index 94d8625b5..000000000
--- a/VirtualApp/lib/src/main/aidl/com/lody/virtual/server/IActivityManager.aidl
+++ /dev/null
@@ -1,116 +0,0 @@
-// IActivityManager.aidl
-package com.lody.virtual.server;
-
-import com.lody.virtual.remote.VParceledListSlice;
-import com.lody.virtual.remote.AppTaskInfo;
-import com.lody.virtual.remote.PendingIntentData;
-import com.lody.virtual.remote.PendingResultData;
-import com.lody.virtual.remote.BadgerInfo;
-import android.content.Intent;
-import android.content.pm.ActivityInfo;
-import android.app.Notification;
-import android.app.IServiceConnection;
-import android.app.IActivityManager.ContentProviderHolder;
-import com.lody.virtual.server.interfaces.IProcessObserver;
-
-
-interface IActivityManager {
-
- int initProcess(in String packageName, in String processName, int userId);
-
- int getFreeStubCount();
-
- int getSystemPid();
-
- int getUidByPid(int pid);
-
- boolean isAppProcess(String processName);
-
- boolean isAppRunning(String packageName, int userId);
-
- boolean isAppPid(int pid);
-
- String getAppProcessName(int pid);
-
- List getProcessPkgList(int pid);
-
- void killAllApps();
-
- void killAppByPkg(String pkg, int userId);
-
- void killApplicationProcess(String procName, int vuid);
-
- void dump();
-
- void registerProcessObserver(in IProcessObserver observer);
-
- void unregisterProcessObserver(in IProcessObserver observer);
-
- String getInitialPackage(int pid);
-
- void handleApplicationCrash();
-
- void appDoneExecuting();
-
- int startActivities(in Intent[] intents, in String[] resolvedTypes, in IBinder token, in Bundle options, in int userId);
-
- int startActivity(in Intent intent, in ActivityInfo info, in IBinder resultTo, in Bundle options, String resultWho, int requestCode, int userId);
-
- void onActivityCreated(in ComponentName component, in ComponentName caller, in IBinder token, in Intent intent, in String affinity, int taskId, int launchMode, int flags);
-
- void onActivityResumed(int userId, in IBinder token);
-
- boolean onActivityDestroyed(int userId, in IBinder token);
-
- ComponentName getActivityClassForToken(int userId, in IBinder token);
-
- String getCallingPackage(int userId, in IBinder token);
-
- ComponentName getCallingActivity(int userId, in IBinder token);
-
- AppTaskInfo getTaskInfo(int taskId);
-
- String getPackageForToken(int userId, in IBinder token);
-
- boolean isVAServiceToken(in IBinder token);
-
- ComponentName startService(in IBinder caller,in Intent service, String resolvedType, int userId);
-
- int stopService(in IBinder caller, in Intent service, String resolvedType, int userId);
-
- boolean stopServiceToken(in ComponentName className, in IBinder token, int startId, int userId);
-
- void setServiceForeground(in ComponentName className, in IBinder token, int id,
- in Notification notification, boolean removeNotification, int userId);
-
- int bindService(in IBinder caller, in IBinder token, in Intent service,
- String resolvedType, in IServiceConnection connection, int flags, int userId);
-
- boolean unbindService(in IServiceConnection connection, int userId);
-
- void unbindFinished(in IBinder token, in Intent service, in boolean doRebind, int userId);
-
- void serviceDoneExecuting(in IBinder token, in int type, in int startId, in int res, int userId);
-
- IBinder peekService(in Intent service, String resolvedType, int userId);
-
- void publishService(in IBinder token, in Intent intent, in IBinder service, int userId);
-
- VParceledListSlice getServices(int maxNum, int flags, int userId);
-
- IBinder acquireProviderClient(int userId, in ProviderInfo info);
-
- PendingIntentData getPendingIntent(IBinder binder);
-
- void addPendingIntent(IBinder binder, String packageName);
-
- void removePendingIntent(IBinder binder);
-
- String getPackageForIntentSender(IBinder binder);
-
- void processRestarted(in String packageName, in String processName, int userId);
-
- void broadcastFinish(in PendingResultData res);
-
- void notifyBadgerChange(in BadgerInfo info);
-}
diff --git a/VirtualApp/lib/src/main/aidl/com/lody/virtual/server/IAppManager.aidl b/VirtualApp/lib/src/main/aidl/com/lody/virtual/server/IAppManager.aidl
deleted file mode 100644
index ca665ed60..000000000
--- a/VirtualApp/lib/src/main/aidl/com/lody/virtual/server/IAppManager.aidl
+++ /dev/null
@@ -1,35 +0,0 @@
-// IAppManager.aidl
-package com.lody.virtual.server;
-
-import com.lody.virtual.server.interfaces.IPackageObserver;
-import com.lody.virtual.server.interfaces.IAppRequestListener;
-import com.lody.virtual.remote.InstalledAppInfo;
-import com.lody.virtual.remote.InstallResult;
-
-interface IAppManager {
- int[] getPackageInstalledUsers(String packageName);
- void scanApps();
- void addVisibleOutsidePackage(String pkg);
- void removeVisibleOutsidePackage(String pkg);
- boolean isOutsidePackageVisible(String pkg);
- InstalledAppInfo getInstalledAppInfo(String pkg, int flags);
- InstallResult installPackage(String path, int flags);
- boolean isPackageLaunched(int userId, String packageName);
- void setPackageHidden(int userId, String packageName, boolean hidden);
- boolean installPackageAsUser(int userId, String packageName);
- boolean uninstallPackageAsUser(String packageName, int userId);
- boolean uninstallPackage(String packageName);
- List getInstalledApps(int flags);
- List getInstalledAppsAsUser(int userId, int flags);
- int getInstalledAppCount();
- boolean isAppInstalled(String packageName);
- boolean isAppInstalledAsUser(int userId, String packageName);
-
- void registerObserver(IPackageObserver observer);
- void unregisterObserver(IPackageObserver observer);
-
- void setAppRequestListener(IAppRequestListener listener);
- void clearAppRequestListener();
- IAppRequestListener getAppRequestListener();
-
-}
diff --git a/VirtualApp/lib/src/main/aidl/com/lody/virtual/server/IDeviceInfoManager.aidl b/VirtualApp/lib/src/main/aidl/com/lody/virtual/server/IDeviceInfoManager.aidl
deleted file mode 100644
index 3305d799d..000000000
--- a/VirtualApp/lib/src/main/aidl/com/lody/virtual/server/IDeviceInfoManager.aidl
+++ /dev/null
@@ -1,12 +0,0 @@
-// IDeviceInfoManager.aidl
-package com.lody.virtual.server;
-
-import com.lody.virtual.remote.VDeviceInfo;
-
-interface IDeviceInfoManager {
-
- VDeviceInfo getDeviceInfo(int userId);
-
- void updateDeviceInfo(int userId, in VDeviceInfo info);
-
-}
diff --git a/VirtualApp/lib/src/main/aidl/com/lody/virtual/server/IJobScheduler.aidl b/VirtualApp/lib/src/main/aidl/com/lody/virtual/server/IJobScheduler.aidl
deleted file mode 100644
index 5e230364c..000000000
--- a/VirtualApp/lib/src/main/aidl/com/lody/virtual/server/IJobScheduler.aidl
+++ /dev/null
@@ -1,13 +0,0 @@
-package com.lody.virtual.server;
-
-import android.app.job.JobInfo;
-
- /**
- * IPC interface that supports the app-facing {@link #JobScheduler} api.
- */
-interface IJobScheduler {
- int schedule(in JobInfo job);
- void cancel(int jobId);
- void cancelAll();
- List getAllPendingJobs();
-}
diff --git a/VirtualApp/lib/src/main/aidl/com/lody/virtual/server/INotificationManager.aidl b/VirtualApp/lib/src/main/aidl/com/lody/virtual/server/INotificationManager.aidl
deleted file mode 100644
index c48b2320d..000000000
--- a/VirtualApp/lib/src/main/aidl/com/lody/virtual/server/INotificationManager.aidl
+++ /dev/null
@@ -1,14 +0,0 @@
-// INotificationManager.aidl
-package com.lody.virtual.server;
-
-// Declare any non-default types here with import statements
-import android.app.Notification;
-
-interface INotificationManager {
- int dealNotificationId(int id, String packageName, String tag, int userId);
- String dealNotificationTag(int id, String packageName, String tag, int userId);
- boolean areNotificationsEnabledForPackage(String packageName, int userId);
- void setNotificationsEnabledForPackage(String packageName, boolean enable, int userId);
- void addNotification(int id, String tag, String packageName, int userId);
- void cancelAllNotification(String packageName, int userId);
-}
diff --git a/VirtualApp/lib/src/main/aidl/com/lody/virtual/server/IPackageManager.aidl b/VirtualApp/lib/src/main/aidl/com/lody/virtual/server/IPackageManager.aidl
deleted file mode 100644
index 973cbf7ef..000000000
--- a/VirtualApp/lib/src/main/aidl/com/lody/virtual/server/IPackageManager.aidl
+++ /dev/null
@@ -1,78 +0,0 @@
-// IPackageManager.aidl
-package com.lody.virtual.server;
-
-import android.content.ComponentName;
-import android.content.Intent;
-import android.content.pm.PackageInfo;
-import android.content.pm.ActivityInfo;
-import android.content.pm.ServiceInfo;
-import android.content.pm.ProviderInfo;
-import android.content.pm.ResolveInfo;
-import android.content.pm.ApplicationInfo;
-import android.content.IntentFilter;
-import android.content.pm.PermissionInfo;
-import android.content.pm.PermissionGroupInfo;
-
-import com.lody.virtual.remote.ReceiverInfo;
-import com.lody.virtual.remote.VParceledListSlice;
-
-import com.lody.virtual.server.IPackageInstaller;
-
-interface IPackageManager {
-
- int getPackageUid(String packageName, int userId);
-
- String[] getPackagesForUid(int vuid);
-
- List getSharedLibraries(String pkgName);
-
- int checkPermission(String permName, String pkgName, int userId);
-
- PackageInfo getPackageInfo(String packageName, int flags, int userId);
-
- ActivityInfo getActivityInfo(in ComponentName componentName, int flags, int userId);
-
- boolean activitySupportsIntent(in ComponentName component, in Intent intent,
- in String resolvedType);
- ActivityInfo getReceiverInfo(in ComponentName componentName, int flags, int userId);
-
- ServiceInfo getServiceInfo(in ComponentName componentName, int flags, int userId);
-
- ProviderInfo getProviderInfo(in ComponentName componentName, int flags, int userId);
-
- ResolveInfo resolveIntent(in Intent intent, in String resolvedType, int flags, int userId);
-
- List queryIntentActivities(in Intent intent,in String resolvedType, int flags, int userId);
-
- List queryIntentReceivers(in Intent intent, String resolvedType, int flags, int userId);
-
- ResolveInfo resolveService(in Intent intent, String resolvedType, int flags, int userId);
-
- List queryIntentServices(in Intent intent, String resolvedType, int flags, int userId);
-
- List queryIntentContentProviders(in Intent intent, String resolvedType, int flags, int userId);
-
- VParceledListSlice getInstalledPackages(int flags, int userId);
-
- VParceledListSlice getInstalledApplications(int flags, int userId);
-
- PermissionInfo getPermissionInfo(in String name, int flags);
-
- List queryPermissionsByGroup(in String group, int flags);
-
- PermissionGroupInfo getPermissionGroupInfo(in String name, int flags);
-
- List getAllPermissionGroups(int flags);
-
- ProviderInfo resolveContentProvider(in String name, int flags, int userId);
-
- ApplicationInfo getApplicationInfo(in String packageName, int flags, int userId);
-
- VParceledListSlice queryContentProviders(in String processName, int vuid, int flags);
-
- List querySharedPackages(in String packageName);
-
- String getNameForUid(int uid);
-
- IPackageInstaller getPackageInstaller();
-}
diff --git a/VirtualApp/lib/src/main/aidl/com/lody/virtual/server/IUserManager.aidl b/VirtualApp/lib/src/main/aidl/com/lody/virtual/server/IUserManager.aidl
deleted file mode 100644
index 1f0faded3..000000000
--- a/VirtualApp/lib/src/main/aidl/com/lody/virtual/server/IUserManager.aidl
+++ /dev/null
@@ -1,23 +0,0 @@
-package com.lody.virtual.server;
-
-import android.os.ParcelFileDescriptor;
-import com.lody.virtual.os.VUserInfo;
-import android.graphics.Bitmap;
-
-/**
-*
- */
-interface IUserManager {
- VUserInfo createUser(in String name, int flags);
- boolean removeUser(int userHandle);
- void setUserName(int userHandle, String name);
- void setUserIcon(int userHandle, in Bitmap icon);
- Bitmap getUserIcon(int userHandle);
- List getUsers(boolean excludeDying);
- VUserInfo getUserInfo(int userHandle);
- void setGuestEnabled(boolean enable);
- boolean isGuestEnabled();
- void wipeUser(int userHandle);
- int getUserSerialNumber(int userHandle);
- int getUserHandle(int userSerialNumber);
-}
diff --git a/VirtualApp/lib/src/main/aidl/com/lody/virtual/server/IVirtualLocationManager.aidl b/VirtualApp/lib/src/main/aidl/com/lody/virtual/server/IVirtualLocationManager.aidl
deleted file mode 100644
index 750319aa8..000000000
--- a/VirtualApp/lib/src/main/aidl/com/lody/virtual/server/IVirtualLocationManager.aidl
+++ /dev/null
@@ -1,30 +0,0 @@
-// IVirtualLocationManager.aidl
-package com.lody.virtual.server;
-
-import com.lody.virtual.remote.vloc.VCell;
-import com.lody.virtual.remote.vloc.VWifi;
-import com.lody.virtual.remote.vloc.VLocation;
-
-interface IVirtualLocationManager {
-
- int getMode(int userId, in String pkg);
- void setMode(int userId, in String pkg, int mode);
-
- void setCell(in int userId, in String pkg, in VCell cell);
- void setAllCell(in int userId, in String pkg, in List cell);
- void setNeighboringCell(in int userId, in String pkg, in List cell);
-
- void setGlobalCell(in VCell cell);
- void setGlobalAllCell(in List cell);
- void setGlobalNeighboringCell(in List cell);
-
- VCell getCell(in int userId, in String pkg);
- List getAllCell(in int userId, in String pkg);
- List getNeighboringCell(in int userId, in String pkg);
-
- void setLocation(in int userId, in String pkg, in VLocation loc);
- VLocation getLocation(in int userId, in String pkg);
-
- void setGlobalLocation(in VLocation loc);
- VLocation getGlobalLocation();
-}
\ No newline at end of file
diff --git a/VirtualApp/lib/src/main/aidl/com/lody/virtual/server/IVirtualStorageService.aidl b/VirtualApp/lib/src/main/aidl/com/lody/virtual/server/IVirtualStorageService.aidl
deleted file mode 100644
index 042b8254b..000000000
--- a/VirtualApp/lib/src/main/aidl/com/lody/virtual/server/IVirtualStorageService.aidl
+++ /dev/null
@@ -1,15 +0,0 @@
-// IVirtualStorageService.aidl
-package com.lody.virtual.server;
-
-
-interface IVirtualStorageService {
-
- void setVirtualStorage(in String packageName, in int userId, in String vsPath);
-
- String getVirtualStorage(in String packageName, in int userId);
-
- void setVirtualStorageState(in String packageName, in int userId, in boolean enable);
-
- boolean isVirtualStorageEnable(in String packageName, in int userId);
-
-}
diff --git a/VirtualApp/lib/src/main/java/com/lody/virtual/client/VClientImpl.java b/VirtualApp/lib/src/main/java/com/lody/virtual/client/VClientImpl.java
index ff8b8349b..3d9bdffc3 100644
--- a/VirtualApp/lib/src/main/java/com/lody/virtual/client/VClientImpl.java
+++ b/VirtualApp/lib/src/main/java/com/lody/virtual/client/VClientImpl.java
@@ -12,6 +12,7 @@
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.ProviderInfo;
+import android.content.res.Configuration;
import android.os.Binder;
import android.os.Build;
import android.os.ConditionVariable;
@@ -20,6 +21,7 @@
import android.os.IInterface;
import android.os.Looper;
import android.os.Message;
+import android.os.Parcelable;
import android.os.Process;
import android.os.RemoteException;
import android.os.StrictMode;
@@ -60,11 +62,17 @@
import mirror.android.app.ActivityThread;
import mirror.android.app.ActivityThreadNMR1;
import mirror.android.app.ContextImpl;
+import mirror.android.app.ContextImplKitkat;
import mirror.android.app.IActivityManager;
import mirror.android.app.LoadedApk;
+import mirror.android.app.LoadedApkICS;
+import mirror.android.app.LoadedApkKitkat;
import mirror.android.content.ContentProviderHolderOreo;
+import mirror.android.content.res.CompatibilityInfo;
import mirror.android.providers.Settings;
import mirror.android.renderscript.RenderScriptCacheDir;
+import mirror.android.view.CompatibilityInfoHolder;
+import mirror.android.view.DisplayAdjustments;
import mirror.android.view.HardwareRenderer;
import mirror.android.view.RenderScript;
import mirror.android.view.ThreadedRenderer;
@@ -266,6 +274,7 @@ private void bindApplicationNoCheck(String packageName, String processName, Cond
} else {
codeCacheDir = context.getCacheDir();
}
+
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
if (HardwareRenderer.setupDiskCache != null) {
HardwareRenderer.setupDiskCache.call(codeCacheDir);
@@ -289,6 +298,17 @@ private void bindApplicationNoCheck(String packageName, String processName, Cond
mirror.android.app.ActivityThread.AppBindData.info.set(boundApp, data.info);
VMRuntime.setTargetSdkVersion.call(VMRuntime.getRuntime.call(), data.appInfo.targetSdkVersion);
+ Configuration configuration = context.getResources().getConfiguration();
+ Object compatInfo = CompatibilityInfo.ctor.newInstance(data.appInfo, configuration.screenLayout, configuration.smallestScreenWidthDp, false);
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
+ DisplayAdjustments.setCompatibilityInfo.call(ContextImplKitkat.mDisplayAdjustments.get(context), compatInfo);
+ }
+ DisplayAdjustments.setCompatibilityInfo.call(LoadedApkKitkat.mDisplayAdjustments.get(mBoundApplication.info), compatInfo);
+ } else {
+ CompatibilityInfoHolder.set.call(LoadedApkICS.mCompatibilityInfo.get(mBoundApplication.info), compatInfo);
+ }
+
boolean conflict = SpecialComponentList.isConflictingInstrumentation(packageName);
if (!conflict) {
InvocationStubManager.getInstance().checkEnv(AppInstrumentation.class);
@@ -358,6 +378,7 @@ private void setupUncaughtHandler() {
groups.add(newRoot);
mirror.java.lang.ThreadGroup.groups.set(root, groups);
for (ThreadGroup group : newGroups) {
+ if (group == newRoot) continue;
mirror.java.lang.ThreadGroup.parent.set(group, newRoot);
}
}
@@ -369,6 +390,7 @@ private void setupUncaughtHandler() {
ThreadGroupN.groups.set(newRoot, newGroups);
ThreadGroupN.groups.set(root, new ThreadGroup[]{newRoot});
for (Object group : newGroups) {
+ if (group == newRoot) continue;
ThreadGroupN.parent.set(group, newRoot);
}
ThreadGroupN.ngroups.set(root, 1);
diff --git a/VirtualApp/lib/src/main/java/com/lody/virtual/client/core/InvocationStubManager.java b/VirtualApp/lib/src/main/java/com/lody/virtual/client/core/InvocationStubManager.java
index 55cc89fab..a7712f023 100644
--- a/VirtualApp/lib/src/main/java/com/lody/virtual/client/core/InvocationStubManager.java
+++ b/VirtualApp/lib/src/main/java/com/lody/virtual/client/core/InvocationStubManager.java
@@ -47,6 +47,7 @@
import com.lody.virtual.client.hook.proxies.usage.UsageStatsManagerStub;
import com.lody.virtual.client.hook.proxies.user.UserManagerStub;
import com.lody.virtual.client.hook.proxies.vibrator.VibratorStub;
+import com.lody.virtual.client.hook.proxies.view.AutoFillManagerStub;
import com.lody.virtual.client.hook.proxies.wifi.WifiManagerStub;
import com.lody.virtual.client.hook.proxies.wifi_scanner.WifiScannerStub;
import com.lody.virtual.client.hook.proxies.window.WindowManagerStub;
@@ -179,6 +180,9 @@ private void injectInternal() throws Throwable {
addInjector(new ShortcutServiceStub());
addInjector(new DevicePolicyManagerStub());
}
+ if (Build.VERSION.SDK_INT >= 26) {
+ addInjector(new AutoFillManagerStub());
+ }
}
}
diff --git a/VirtualApp/lib/src/main/java/com/lody/virtual/client/core/VirtualCore.java b/VirtualApp/lib/src/main/java/com/lody/virtual/client/core/VirtualCore.java
index 2a9d7a4fc..bf77a3fe3 100644
--- a/VirtualApp/lib/src/main/java/com/lody/virtual/client/core/VirtualCore.java
+++ b/VirtualApp/lib/src/main/java/com/lody/virtual/client/core/VirtualCore.java
@@ -16,6 +16,7 @@
import android.graphics.Bitmap;
import android.os.Bundle;
import android.os.ConditionVariable;
+import android.os.IBinder;
import android.os.Looper;
import android.os.Process;
import android.os.RemoteException;
@@ -28,17 +29,20 @@
import com.lody.virtual.client.hook.delegate.ComponentDelegate;
import com.lody.virtual.client.hook.delegate.PhoneInfoDelegate;
import com.lody.virtual.client.hook.delegate.TaskDescriptionDelegate;
-import com.lody.virtual.client.ipc.LocalProxyUtils;
import com.lody.virtual.client.ipc.ServiceManagerNative;
import com.lody.virtual.client.ipc.VActivityManager;
import com.lody.virtual.client.ipc.VPackageManager;
import com.lody.virtual.client.stub.VASettings;
import com.lody.virtual.helper.compat.BundleCompat;
+import com.lody.virtual.helper.ipcbus.IPCBus;
+import com.lody.virtual.helper.ipcbus.IPCSingleton;
+import com.lody.virtual.helper.ipcbus.IServerCache;
import com.lody.virtual.helper.utils.BitmapUtils;
import com.lody.virtual.os.VUserHandle;
import com.lody.virtual.remote.InstallResult;
import com.lody.virtual.remote.InstalledAppInfo;
-import com.lody.virtual.server.IAppManager;
+import com.lody.virtual.server.interfaces.IAppManager;
+import com.lody.virtual.server.ServiceCache;
import com.lody.virtual.server.interfaces.IAppRequestListener;
import com.lody.virtual.server.interfaces.IPackageObserver;
import com.lody.virtual.server.interfaces.IUiCallback;
@@ -82,7 +86,7 @@ public final class VirtualCore {
*/
private String processName;
private ProcessType processType;
- private IAppManager mService;
+ private IPCSingleton singleton = new IPCSingleton<>(IAppManager.class);
private boolean isStartUp;
private PackageInfo hostPkgInfo;
private int systemPid;
@@ -178,6 +182,17 @@ public void startup(Context context) throws Throwable {
mainThread = ActivityThread.currentActivityThread.call();
unHookPackageManager = context.getPackageManager();
hostPkgInfo = unHookPackageManager.getPackageInfo(context.getPackageName(), PackageManager.GET_PROVIDERS);
+ IPCBus.initialize(new IServerCache() {
+ @Override
+ public void join(String serverName, IBinder binder) {
+ ServiceCache.addService(serverName, binder);
+ }
+
+ @Override
+ public IBinder query(String serverName) {
+ return ServiceManagerNative.getService(serverName);
+ }
+ });
detectProcessType();
InvocationStubManager invocationStubManager = InvocationStubManager.getInstance();
invocationStubManager.init();
@@ -252,19 +267,7 @@ private void detectProcessType() {
}
private IAppManager getService() {
- if (mService == null
- || (!VirtualCore.get().isVAppProcess() && !mService.asBinder().isBinderAlive())) {
- synchronized (this) {
- Object remote = getStubInterface();
- mService = LocalProxyUtils.genProxy(IAppManager.class, remote);
- }
- }
- return mService;
- }
-
- private Object getStubInterface() {
- return IAppManager.Stub
- .asInterface(ServiceManagerNative.getService(ServiceManagerNative.APP));
+ return singleton.get();
}
/**
diff --git a/VirtualApp/lib/src/main/java/com/lody/virtual/client/env/SpecialComponentList.java b/VirtualApp/lib/src/main/java/com/lody/virtual/client/env/SpecialComponentList.java
index 9d1872b22..91c95e88f 100644
--- a/VirtualApp/lib/src/main/java/com/lody/virtual/client/env/SpecialComponentList.java
+++ b/VirtualApp/lib/src/main/java/com/lody/virtual/client/env/SpecialComponentList.java
@@ -43,6 +43,7 @@ public final class SpecialComponentList {
SYSTEM_BROADCAST_ACTION.add(Intent.ACTION_BATTERY_OKAY);
SYSTEM_BROADCAST_ACTION.add(Intent.ACTION_POWER_CONNECTED);
SYSTEM_BROADCAST_ACTION.add(Intent.ACTION_POWER_DISCONNECTED);
+ SYSTEM_BROADCAST_ACTION.add(Intent.ACTION_USER_PRESENT);
SYSTEM_BROADCAST_ACTION.add("android.provider.Telephony.SMS_RECEIVED");
SYSTEM_BROADCAST_ACTION.add("android.provider.Telephony.SMS_DELIVER");
SYSTEM_BROADCAST_ACTION.add("android.net.wifi.STATE_CHANGE");
diff --git a/VirtualApp/lib/src/main/java/com/lody/virtual/client/hook/proxies/am/ActivityManagerStub.java b/VirtualApp/lib/src/main/java/com/lody/virtual/client/hook/proxies/am/ActivityManagerStub.java
index 077514925..329f54207 100644
--- a/VirtualApp/lib/src/main/java/com/lody/virtual/client/hook/proxies/am/ActivityManagerStub.java
+++ b/VirtualApp/lib/src/main/java/com/lody/virtual/client/hook/proxies/am/ActivityManagerStub.java
@@ -115,27 +115,6 @@ public Object call(Object who, Method method, Object... args) throws Throwable {
return _infos;
}
});
- addMethodProxy(new StaticMethodProxy("getRunningTasks") {
- @Override
- public Object call(Object who, Method method, Object... args) throws Throwable {
- Object _infos = method.invoke(who, args);
- //noinspection unchecked
- List infos =
- ParceledListSliceCompat.isReturnParceledListSlice(method)
- ? ParceledListSlice.getList.call(_infos)
- : (List) _infos;
- for (ActivityManager.RunningTaskInfo info : infos) {
- AppTaskInfo taskInfo = VActivityManager.get().getTaskInfo(info.id);
- if (taskInfo == null) {
- continue;
- }
- info.description = "Virtual";
- info.topActivity = taskInfo.topActivity;
- info.baseActivity = taskInfo.baseActivity;
- }
- return _infos;
- }
- });
}
}
diff --git a/VirtualApp/lib/src/main/java/com/lody/virtual/client/hook/proxies/am/MethodProxies.java b/VirtualApp/lib/src/main/java/com/lody/virtual/client/hook/proxies/am/MethodProxies.java
index d49d1052f..2ae83489f 100644
--- a/VirtualApp/lib/src/main/java/com/lody/virtual/client/hook/proxies/am/MethodProxies.java
+++ b/VirtualApp/lib/src/main/java/com/lody/virtual/client/hook/proxies/am/MethodProxies.java
@@ -28,6 +28,7 @@
import android.os.IInterface;
import android.os.RemoteException;
import android.text.TextUtils;
+import android.util.Log;
import android.util.TypedValue;
import com.lody.virtual.client.VClientImpl;
@@ -55,6 +56,7 @@
import com.lody.virtual.helper.utils.BitmapUtils;
import com.lody.virtual.helper.utils.ComponentUtils;
import com.lody.virtual.helper.utils.DrawableUtils;
+import com.lody.virtual.helper.utils.FileUtils;
import com.lody.virtual.helper.utils.Reflect;
import com.lody.virtual.helper.utils.VLog;
import com.lody.virtual.os.VUserHandle;
@@ -63,6 +65,10 @@
import com.lody.virtual.server.interfaces.IAppRequestListener;
import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
import java.lang.ref.WeakReference;
import java.lang.reflect.Method;
import java.util.List;
@@ -74,6 +80,8 @@
import mirror.android.content.IIntentReceiverJB;
import mirror.android.content.pm.UserInfo;
+import static com.lody.virtual.client.stub.VASettings.INTERCEPT_BACK_HOME;
+
/**
* @author Lody
*/
@@ -360,6 +368,7 @@ static class StartActivity extends MethodProxy {
private static final String SCHEME_FILE = "file";
private static final String SCHEME_PACKAGE = "package";
+ private static final String SCHEME_CONTENT = "content";
@Override
public String getMethodName() {
@@ -368,6 +377,9 @@ public String getMethodName() {
@Override
public Object call(Object who, Method method, Object... args) throws Throwable {
+
+ Log.d("Q_M", "---->StartActivity 类");
+
int intentIndex = ArrayUtils.indexOfObject(args, Intent.class, 1);
if (intentIndex < 0) {
return ActivityManagerCompat.START_INTENT_NOT_RESOLVED;
@@ -427,9 +439,22 @@ public Object call(Object who, Method method, Object... args) throws Throwable {
ActivityInfo activityInfo = VirtualCore.get().resolveActivityInfo(intent, userId);
if (activityInfo == null) {
VLog.e("VActivityManager", "Unable to resolve activityInfo : " + intent);
+
+ Log.d("Q_M", "---->StartActivity who=" + who);
+ Log.d("Q_M", "---->StartActivity intent=" + intent);
+ Log.d("Q_M", "---->StartActivity resultTo=" + resultTo);
+
if (intent.getPackage() != null && isAppPkg(intent.getPackage())) {
return ActivityManagerCompat.START_INTENT_NOT_RESOLVED;
}
+
+ if (INTERCEPT_BACK_HOME && Intent.ACTION_MAIN.equals(intent.getAction())
+ && intent.getCategories().contains("android.intent.category.HOME")
+ && resultTo != null) {
+ VActivityManager.get().finishActivity(resultTo);
+ return 0;
+ }
+
return method.invoke(who, args);
}
int res = VActivityManager.get().startActivity(intent, activityInfo, resultTo, options, resultWho, requestCode, VUserHandle.myUserId());
@@ -475,6 +500,32 @@ private boolean handleInstallRequest(Intent intent) {
} catch (RemoteException e) {
e.printStackTrace();
}
+ } else if (SCHEME_CONTENT.equals(packageUri.getScheme())) {
+ InputStream inputStream = null;
+ OutputStream outputStream = null;
+ File sharedFileCopy = new File(getHostContext().getCacheDir(), packageUri.getLastPathSegment());
+ try {
+ inputStream = getHostContext().getContentResolver().openInputStream(packageUri);
+ outputStream = new FileOutputStream(sharedFileCopy);
+ byte[] buffer = new byte[1024];
+ int count;
+ while ((count = inputStream.read(buffer)) > 0) {
+ outputStream.write(buffer, 0, count);
+ }
+ outputStream.flush();
+
+ } catch (IOException e) {
+ e.printStackTrace();
+ } finally {
+ FileUtils.closeQuietly(inputStream);
+ FileUtils.closeQuietly(outputStream);
+ }
+ try {
+ listener.onRequestInstall(sharedFileCopy.getPath());
+ return true;
+ } catch (RemoteException e) {
+ e.printStackTrace();
+ }
}
}
diff --git a/VirtualApp/lib/src/main/java/com/lody/virtual/client/hook/proxies/bluetooth/BluetoothStub.java b/VirtualApp/lib/src/main/java/com/lody/virtual/client/hook/proxies/bluetooth/BluetoothStub.java
index 9590cab43..1eb15b4ff 100644
--- a/VirtualApp/lib/src/main/java/com/lody/virtual/client/hook/proxies/bluetooth/BluetoothStub.java
+++ b/VirtualApp/lib/src/main/java/com/lody/virtual/client/hook/proxies/bluetooth/BluetoothStub.java
@@ -9,6 +9,7 @@
import java.lang.reflect.Method;
import mirror.android.bluetooth.IBluetooth;
+import mirror.android.bluetooth.IBluetoothManager;
/**
* @see android.bluetooth.BluetoothManager
@@ -19,7 +20,8 @@ public class BluetoothStub extends BinderInvocationProxy {
"bluetooth";
public BluetoothStub() {
- super(IBluetooth.Stub.asInterface, SERVICE_NAME);
+ super(Build.VERSION.SDK_INT >= 17 ? IBluetoothManager.Stub.asInterface : IBluetooth.Stub.asInterface,
+ SERVICE_NAME);
}
@Override
diff --git a/VirtualApp/lib/src/main/java/com/lody/virtual/client/hook/proxies/job/JobServiceStub.java b/VirtualApp/lib/src/main/java/com/lody/virtual/client/hook/proxies/job/JobServiceStub.java
index 2682c4032..8b665938a 100644
--- a/VirtualApp/lib/src/main/java/com/lody/virtual/client/hook/proxies/job/JobServiceStub.java
+++ b/VirtualApp/lib/src/main/java/com/lody/virtual/client/hook/proxies/job/JobServiceStub.java
@@ -3,91 +3,142 @@
import android.annotation.TargetApi;
import android.app.job.JobInfo;
import android.content.Context;
+import android.content.Intent;
import android.os.Build;
+import android.os.Build.VERSION;
import com.lody.virtual.client.hook.base.MethodProxy;
import com.lody.virtual.client.hook.base.BinderInvocationProxy;
import com.lody.virtual.client.ipc.VJobScheduler;
+import com.lody.virtual.helper.utils.ComponentUtils;
import java.lang.reflect.Method;
import mirror.android.app.job.IJobScheduler;
+import mirror.android.app.job.JobWorkItem;
/**
* @author Lody
- *
* @see android.app.job.JobScheduler
*/
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public class JobServiceStub extends BinderInvocationProxy {
- public JobServiceStub() {
- super(IJobScheduler.Stub.asInterface, Context.JOB_SCHEDULER_SERVICE);
- }
-
- @Override
- protected void onBindMethods() {
- super.onBindMethods();
- addMethodProxy(new schedule());
- addMethodProxy(new getAllPendingJobs());
- addMethodProxy(new cancelAll());
- addMethodProxy(new cancel());
- }
-
-
- private class schedule extends MethodProxy {
-
- @Override
- public String getMethodName() {
- return "schedule";
- }
-
- @Override
- public Object call(Object who, Method method, Object... args) throws Throwable {
- JobInfo jobInfo = (JobInfo) args[0];
- return VJobScheduler.get().schedule(jobInfo);
- }
- }
-
- private class getAllPendingJobs extends MethodProxy {
-
- @Override
- public String getMethodName() {
- return "getAllPendingJobs";
- }
-
- @Override
- public Object call(Object who, Method method, Object... args) throws Throwable {
- return VJobScheduler.get().getAllPendingJobs();
- }
- }
-
- private class cancelAll extends MethodProxy {
-
- @Override
- public String getMethodName() {
- return "cancelAll";
- }
-
- @Override
- public Object call(Object who, Method method, Object... args) throws Throwable {
- VJobScheduler.get().cancelAll();
- return 0;
- }
- }
-
- private class cancel extends MethodProxy {
-
- @Override
- public String getMethodName() {
- return "cancel";
- }
-
- @Override
- public Object call(Object who, Method method, Object... args) throws Throwable {
- int jobId = (int) args[0];
- VJobScheduler.get().cancel(jobId);
- return 0;
- }
- }
+ public JobServiceStub() {
+ super(IJobScheduler.Stub.asInterface, Context.JOB_SCHEDULER_SERVICE);
+ }
+
+ @Override
+ protected void onBindMethods() {
+ super.onBindMethods();
+ addMethodProxy(new schedule());
+ addMethodProxy(new getAllPendingJobs());
+ addMethodProxy(new cancelAll());
+ addMethodProxy(new cancel());
+
+ if (VERSION.SDK_INT >= 24) {
+ addMethodProxy(new getPendingJob());
+ }
+ if (VERSION.SDK_INT >= 26) {
+ addMethodProxy(new enqueue());
+ }
+ }
+
+
+ private class schedule extends MethodProxy {
+
+ @Override
+ public String getMethodName() {
+ return "schedule";
+ }
+
+ @Override
+ public Object call(Object who, Method method, Object... args) throws Throwable {
+ JobInfo jobInfo = (JobInfo) args[0];
+ return VJobScheduler.get().schedule(jobInfo);
+ }
+ }
+
+ private class getAllPendingJobs extends MethodProxy {
+
+ @Override
+ public String getMethodName() {
+ return "getAllPendingJobs";
+ }
+
+ @Override
+ public Object call(Object who, Method method, Object... args) throws Throwable {
+ return VJobScheduler.get().getAllPendingJobs();
+ }
+ }
+
+ private class cancelAll extends MethodProxy {
+
+ @Override
+ public String getMethodName() {
+ return "cancelAll";
+ }
+
+ @Override
+ public Object call(Object who, Method method, Object... args) throws Throwable {
+ VJobScheduler.get().cancelAll();
+ return 0;
+ }
+ }
+
+ private class cancel extends MethodProxy {
+
+ @Override
+ public String getMethodName() {
+ return "cancel";
+ }
+
+ @Override
+ public Object call(Object who, Method method, Object... args) throws Throwable {
+ int jobId = (int) args[0];
+ VJobScheduler.get().cancel(jobId);
+ return 0;
+ }
+ }
+
+ private class getPendingJob extends MethodProxy {
+ private getPendingJob() {
+ }
+
+ public Object call(Object who, Method method, Object... args) throws Throwable {
+ return VJobScheduler.get().getPendingJob((Integer) args[0]);
+ }
+
+ public String getMethodName() {
+ return "getPendingJob";
+ }
+ }
+
+ private class enqueue extends MethodProxy {
+ private enqueue() {
+ }
+
+ public Object call(Object who, Method method, Object... args) throws Throwable {
+ return VJobScheduler.get().enqueue(
+ (JobInfo) args[0],
+ JobServiceStub.this.redirect(args[1], MethodProxy.getAppPkg())
+ );
+ }
+
+ public String getMethodName() {
+ return "enqueue";
+ }
+ }
+
+ private Object redirect(Object item, String pkg) {
+ if (item == null) {
+ return null;
+ }
+ Intent redirectIntentSender = ComponentUtils.redirectIntentSender(4, pkg, (Intent) JobWorkItem.getIntent.call(item, new Object[0]), null);
+ Object newInstance = JobWorkItem.ctor.newInstance(redirectIntentSender);
+ JobWorkItem.mWorkId.set(newInstance, JobWorkItem.mWorkId.get(item));
+ JobWorkItem.mGrants.set(newInstance, JobWorkItem.mGrants.get(item));
+ JobWorkItem.mDeliveryCount.set(newInstance, JobWorkItem.mDeliveryCount.get(item));
+ return newInstance;
+ }
}
diff --git a/VirtualApp/lib/src/main/java/com/lody/virtual/client/hook/proxies/location/MethodProxies.java b/VirtualApp/lib/src/main/java/com/lody/virtual/client/hook/proxies/location/MethodProxies.java
index 7aa156b8e..9edefbb3e 100644
--- a/VirtualApp/lib/src/main/java/com/lody/virtual/client/hook/proxies/location/MethodProxies.java
+++ b/VirtualApp/lib/src/main/java/com/lody/virtual/client/hook/proxies/location/MethodProxies.java
@@ -282,7 +282,7 @@ public String getMethodName() {
@Override
public Object afterCall(Object who, Method method, Object[] args, Object result) throws Throwable {
- if (isFakeLocationEnable()) {
+ if (!isFakeLocationEnable()) {
return super.afterCall(who, method, args, result);
}
try {
diff --git a/VirtualApp/lib/src/main/java/com/lody/virtual/client/hook/proxies/view/AutoFillManagerStub.java b/VirtualApp/lib/src/main/java/com/lody/virtual/client/hook/proxies/view/AutoFillManagerStub.java
new file mode 100644
index 000000000..27c898c2c
--- /dev/null
+++ b/VirtualApp/lib/src/main/java/com/lody/virtual/client/hook/proxies/view/AutoFillManagerStub.java
@@ -0,0 +1,83 @@
+package com.lody.virtual.client.hook.proxies.view;
+
+import android.annotation.SuppressLint;
+import android.util.Log;
+
+import com.lody.virtual.client.hook.base.BinderInvocationProxy;
+import com.lody.virtual.client.hook.base.MethodProxy;
+import com.lody.virtual.client.hook.utils.MethodParameterUtils;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+
+import mirror.android.view.IAutoFillManager;
+
+/**
+ * @author 陈磊.
+ */
+
+public class AutoFillManagerStub extends BinderInvocationProxy {
+
+ private static final String TAG = "AutoFillManagerStub";
+
+ private static final String AUTO_FILL_NAME = "autofill";
+ public AutoFillManagerStub() {
+ super(IAutoFillManager.Stub.asInterface, AUTO_FILL_NAME);
+ }
+
+ @SuppressLint("WrongConstant")
+ @Override
+ public void inject() throws Throwable {
+ super.inject();
+ try {
+ Object AutoFillManagerInstance = getContext().getSystemService(AUTO_FILL_NAME);
+ if (AutoFillManagerInstance == null) {
+ throw new NullPointerException("AutoFillManagerInstance is null.");
+ }
+ Object AutoFillManagerProxy = getInvocationStub().getProxyInterface();
+ if (AutoFillManagerProxy == null) {
+ throw new NullPointerException("AutoFillManagerProxy is null.");
+ }
+ Field AutoFillManagerServiceField = AutoFillManagerInstance.getClass().getDeclaredField("mService");
+ AutoFillManagerServiceField.setAccessible(true);
+ AutoFillManagerServiceField.set(AutoFillManagerInstance, AutoFillManagerProxy);
+ } catch (Throwable tr) {
+ Log.e(TAG, "AutoFillManagerStub inject error.", tr);
+ return;
+ }
+ addMethodProxy(new MethodProxy() {
+ @Override
+ public String getMethodName() {
+ return "startSession";
+ }
+ @Override
+ public boolean beforeCall(Object who, Method method, Object... args) {
+ MethodParameterUtils.replaceLastAppPkg(args);
+ return super.beforeCall(who, method, args);
+ }
+ });
+ addMethodProxy(new MethodProxy() {
+ @Override
+ public String getMethodName() {
+ return "updateOrRestartSession";
+ }
+ @Override
+ public boolean beforeCall(Object who, Method method, Object... args) {
+ MethodParameterUtils.replaceLastAppPkg(args);
+ return super.beforeCall(who, method, args);
+ }
+ });
+ addMethodProxy(new MethodProxy() {
+ @Override
+ public String getMethodName() {
+ return "isServiceEnabled";
+ }
+ @Override
+ public boolean beforeCall(Object who, Method method, Object... args) {
+ MethodParameterUtils.replaceLastAppPkg(args);
+ return super.beforeCall(who, method, args);
+ }
+ });
+ }
+
+}
diff --git a/VirtualApp/lib/src/main/java/com/lody/virtual/client/ipc/VAccountManager.java b/VirtualApp/lib/src/main/java/com/lody/virtual/client/ipc/VAccountManager.java
index 084adaf37..075b779be 100644
--- a/VirtualApp/lib/src/main/java/com/lody/virtual/client/ipc/VAccountManager.java
+++ b/VirtualApp/lib/src/main/java/com/lody/virtual/client/ipc/VAccountManager.java
@@ -10,11 +10,11 @@
import android.os.Handler;
import android.os.RemoteException;
-import com.lody.virtual.client.core.VirtualCore;
import com.lody.virtual.client.env.VirtualRuntime;
import com.lody.virtual.client.stub.AmsTask;
+import com.lody.virtual.helper.ipcbus.IPCSingleton;
import com.lody.virtual.os.VUserHandle;
-import com.lody.virtual.server.IAccountManager;
+import com.lody.virtual.server.interfaces.IAccountManager;
import static com.lody.virtual.helper.compat.AccountManagerCompat.KEY_ANDROID_PACKAGE_NAME;
@@ -26,31 +26,19 @@ public class VAccountManager {
private static VAccountManager sMgr = new VAccountManager();
- private IAccountManager mRemote;
+ private IPCSingleton singleton = new IPCSingleton<>(IAccountManager.class);
public static VAccountManager get() {
return sMgr;
}
- public IAccountManager getRemote() {
- if (mRemote == null ||
- (!mRemote.asBinder().isBinderAlive() && !VirtualCore.get().isVAppProcess())) {
- synchronized (VAccountManager.class) {
- Object remote = getStubInterface();
- mRemote = LocalProxyUtils.genProxy(IAccountManager.class, remote);
- }
- }
- return mRemote;
- }
-
- private Object getStubInterface() {
- return IAccountManager.Stub
- .asInterface(ServiceManagerNative.getService(ServiceManagerNative.ACCOUNT));
+ public IAccountManager getService() {
+ return singleton.get();
}
public AuthenticatorDescription[] getAuthenticatorTypes() {
try {
- return getRemote().getAuthenticatorTypes(VUserHandle.myUserId());
+ return getService().getAuthenticatorTypes(VUserHandle.myUserId());
} catch (RemoteException e) {
return VirtualRuntime.crash(e);
}
@@ -58,7 +46,7 @@ public AuthenticatorDescription[] getAuthenticatorTypes() {
public void removeAccount(IAccountManagerResponse response, Account account, boolean expectActivityLaunch) {
try {
- getRemote().removeAccount(VUserHandle.myUserId(), response, account, expectActivityLaunch);
+ getService().removeAccount(VUserHandle.myUserId(), response, account, expectActivityLaunch);
} catch (RemoteException e) {
e.printStackTrace();
}
@@ -66,7 +54,7 @@ public void removeAccount(IAccountManagerResponse response, Account account, boo
public void getAuthToken(IAccountManagerResponse response, Account account, String authTokenType, boolean notifyOnAuthFailure, boolean expectActivityLaunch, Bundle loginOptions) {
try {
- getRemote().getAuthToken(VUserHandle.myUserId(), response, account, authTokenType, notifyOnAuthFailure, expectActivityLaunch, loginOptions);
+ getService().getAuthToken(VUserHandle.myUserId(), response, account, authTokenType, notifyOnAuthFailure, expectActivityLaunch, loginOptions);
} catch (RemoteException e) {
e.printStackTrace();
}
@@ -74,7 +62,7 @@ public void getAuthToken(IAccountManagerResponse response, Account account, Stri
public boolean addAccountExplicitly(Account account, String password, Bundle extras) {
try {
- return getRemote().addAccountExplicitly(VUserHandle.myUserId(), account, password, extras);
+ return getService().addAccountExplicitly(VUserHandle.myUserId(), account, password, extras);
} catch (RemoteException e) {
return VirtualRuntime.crash(e);
}
@@ -82,7 +70,7 @@ public boolean addAccountExplicitly(Account account, String password, Bundle ext
public Account[] getAccounts(int userId, String type) {
try {
- return getRemote().getAccounts(userId, type);
+ return getService().getAccounts(userId, type);
} catch (RemoteException e) {
return VirtualRuntime.crash(e);
}
@@ -90,7 +78,7 @@ public Account[] getAccounts(int userId, String type) {
public Account[] getAccounts(String type) {
try {
- return getRemote().getAccounts(VUserHandle.myUserId(), type);
+ return getService().getAccounts(VUserHandle.myUserId(), type);
} catch (RemoteException e) {
return VirtualRuntime.crash(e);
}
@@ -98,7 +86,7 @@ public Account[] getAccounts(String type) {
public String peekAuthToken(Account account, String authTokenType) {
try {
- return getRemote().peekAuthToken(VUserHandle.myUserId(), account, authTokenType);
+ return getService().peekAuthToken(VUserHandle.myUserId(), account, authTokenType);
} catch (RemoteException e) {
return VirtualRuntime.crash(e);
}
@@ -106,7 +94,7 @@ public String peekAuthToken(Account account, String authTokenType) {
public String getPreviousName(Account account) {
try {
- return getRemote().getPreviousName(VUserHandle.myUserId(), account);
+ return getService().getPreviousName(VUserHandle.myUserId(), account);
} catch (RemoteException e) {
return VirtualRuntime.crash(e);
}
@@ -114,7 +102,7 @@ public String getPreviousName(Account account) {
public void hasFeatures(IAccountManagerResponse response, Account account, String[] features) {
try {
- getRemote().hasFeatures(VUserHandle.myUserId(), response, account, features);
+ getService().hasFeatures(VUserHandle.myUserId(), response, account, features);
} catch (RemoteException e) {
e.printStackTrace();
}
@@ -122,7 +110,7 @@ public void hasFeatures(IAccountManagerResponse response, Account account, Strin
public boolean accountAuthenticated(Account account) {
try {
- return getRemote().accountAuthenticated(VUserHandle.myUserId(), account);
+ return getService().accountAuthenticated(VUserHandle.myUserId(), account);
} catch (RemoteException e) {
return VirtualRuntime.crash(e);
}
@@ -130,7 +118,7 @@ public boolean accountAuthenticated(Account account) {
public void clearPassword(Account account) {
try {
- getRemote().clearPassword(VUserHandle.myUserId(), account);
+ getService().clearPassword(VUserHandle.myUserId(), account);
} catch (RemoteException e) {
e.printStackTrace();
}
@@ -138,7 +126,7 @@ public void clearPassword(Account account) {
public void renameAccount(IAccountManagerResponse response, Account accountToRename, String newName) {
try {
- getRemote().renameAccount(VUserHandle.myUserId(), response, accountToRename, newName);
+ getService().renameAccount(VUserHandle.myUserId(), response, accountToRename, newName);
} catch (RemoteException e) {
e.printStackTrace();
}
@@ -146,7 +134,7 @@ public void renameAccount(IAccountManagerResponse response, Account accountToRen
public void setPassword(Account account, String password) {
try {
- getRemote().setPassword(VUserHandle.myUserId(), account, password);
+ getService().setPassword(VUserHandle.myUserId(), account, password);
} catch (RemoteException e) {
e.printStackTrace();
}
@@ -154,7 +142,7 @@ public void setPassword(Account account, String password) {
public void addAccount(int userId, IAccountManagerResponse response, String accountType, String authTokenType, String[] requiredFeatures, boolean expectActivityLaunch, Bundle optionsIn) {
try {
- getRemote().addAccount(userId, response, accountType, authTokenType, requiredFeatures, expectActivityLaunch, optionsIn);
+ getService().addAccount(userId, response, accountType, authTokenType, requiredFeatures, expectActivityLaunch, optionsIn);
} catch (RemoteException e) {
e.printStackTrace();
}
@@ -162,7 +150,7 @@ public void addAccount(int userId, IAccountManagerResponse response, String acco
public void addAccount(IAccountManagerResponse response, String accountType, String authTokenType, String[] requiredFeatures, boolean expectActivityLaunch, Bundle optionsIn) {
try {
- getRemote().addAccount(VUserHandle.myUserId(), response, accountType, authTokenType, requiredFeatures, expectActivityLaunch, optionsIn);
+ getService().addAccount(VUserHandle.myUserId(), response, accountType, authTokenType, requiredFeatures, expectActivityLaunch, optionsIn);
} catch (RemoteException e) {
e.printStackTrace();
}
@@ -170,7 +158,7 @@ public void addAccount(IAccountManagerResponse response, String accountType, Str
public void updateCredentials(IAccountManagerResponse response, Account account, String authTokenType, boolean expectActivityLaunch, Bundle loginOptions) {
try {
- getRemote().updateCredentials(VUserHandle.myUserId(), response, account, authTokenType, expectActivityLaunch, loginOptions);
+ getService().updateCredentials(VUserHandle.myUserId(), response, account, authTokenType, expectActivityLaunch, loginOptions);
} catch (RemoteException e) {
e.printStackTrace();
}
@@ -178,7 +166,7 @@ public void updateCredentials(IAccountManagerResponse response, Account account,
public boolean removeAccountExplicitly(Account account) {
try {
- return getRemote().removeAccountExplicitly(VUserHandle.myUserId(), account);
+ return getService().removeAccountExplicitly(VUserHandle.myUserId(), account);
} catch (RemoteException e) {
return VirtualRuntime.crash(e);
}
@@ -186,7 +174,7 @@ public boolean removeAccountExplicitly(Account account) {
public void setUserData(Account account, String key, String value) {
try {
- getRemote().setUserData(VUserHandle.myUserId(), account, key, value);
+ getService().setUserData(VUserHandle.myUserId(), account, key, value);
} catch (RemoteException e) {
e.printStackTrace();
}
@@ -194,7 +182,7 @@ public void setUserData(Account account, String key, String value) {
public void editProperties(IAccountManagerResponse response, String accountType, boolean expectActivityLaunch) {
try {
- getRemote().editProperties(VUserHandle.myUserId(), response, accountType, expectActivityLaunch);
+ getService().editProperties(VUserHandle.myUserId(), response, accountType, expectActivityLaunch);
} catch (RemoteException e) {
e.printStackTrace();
}
@@ -202,7 +190,7 @@ public void editProperties(IAccountManagerResponse response, String accountType,
public void getAuthTokenLabel(IAccountManagerResponse response, String accountType, String authTokenType) {
try {
- getRemote().getAuthTokenLabel(VUserHandle.myUserId(), response, accountType, authTokenType);
+ getService().getAuthTokenLabel(VUserHandle.myUserId(), response, accountType, authTokenType);
} catch (RemoteException e) {
e.printStackTrace();
}
@@ -210,7 +198,7 @@ public void getAuthTokenLabel(IAccountManagerResponse response, String accountTy
public void confirmCredentials(IAccountManagerResponse response, Account account, Bundle options, boolean expectActivityLaunch) {
try {
- getRemote().confirmCredentials(VUserHandle.myUserId(), response, account, options, expectActivityLaunch);
+ getService().confirmCredentials(VUserHandle.myUserId(), response, account, options, expectActivityLaunch);
} catch (RemoteException e) {
e.printStackTrace();
}
@@ -218,7 +206,7 @@ public void confirmCredentials(IAccountManagerResponse response, Account account
public void invalidateAuthToken(String accountType, String authToken) {
try {
- getRemote().invalidateAuthToken(VUserHandle.myUserId(), accountType, authToken);
+ getService().invalidateAuthToken(VUserHandle.myUserId(), accountType, authToken);
} catch (RemoteException e) {
e.printStackTrace();
}
@@ -226,7 +214,7 @@ public void invalidateAuthToken(String accountType, String authToken) {
public void getAccountsByFeatures(IAccountManagerResponse response, String type, String[] features) {
try {
- getRemote().getAccountsByFeatures(VUserHandle.myUserId(), response, type, features);
+ getService().getAccountsByFeatures(VUserHandle.myUserId(), response, type, features);
} catch (RemoteException e) {
e.printStackTrace();
}
@@ -234,7 +222,7 @@ public void getAccountsByFeatures(IAccountManagerResponse response, String type,
public void setAuthToken(Account account, String authTokenType, String authToken) {
try {
- getRemote().setAuthToken(VUserHandle.myUserId(), account, authTokenType, authToken);
+ getService().setAuthToken(VUserHandle.myUserId(), account, authTokenType, authToken);
} catch (RemoteException e) {
e.printStackTrace();
}
@@ -242,7 +230,7 @@ public void setAuthToken(Account account, String authTokenType, String authToken
public Object getPassword(Account account) {
try {
- return getRemote().getPassword(VUserHandle.myUserId(), account);
+ return getService().getPassword(VUserHandle.myUserId(), account);
} catch (RemoteException e) {
return VirtualRuntime.crash(e);
}
@@ -250,7 +238,7 @@ public Object getPassword(Account account) {
public String getUserData(Account account, String key) {
try {
- return getRemote().getUserData(VUserHandle.myUserId(), account, key);
+ return getService().getUserData(VUserHandle.myUserId(), account, key);
} catch (RemoteException e) {
return VirtualRuntime.crash(e);
}
@@ -265,7 +253,6 @@ public String getUserData(Account account, String key) {
*
This method may be called from any thread, but the returned
* {@link AccountManagerFuture} must not be used on the main thread.
*
- *
*/
public AccountManagerFuture addAccount(final int userId, final String accountType,
final String authTokenType, final String[] requiredFeatures,
diff --git a/VirtualApp/lib/src/main/java/com/lody/virtual/client/ipc/VActivityManager.java b/VirtualApp/lib/src/main/java/com/lody/virtual/client/ipc/VActivityManager.java
index c9ab8e09f..b4a7a537b 100644
--- a/VirtualApp/lib/src/main/java/com/lody/virtual/client/ipc/VActivityManager.java
+++ b/VirtualApp/lib/src/main/java/com/lody/virtual/client/ipc/VActivityManager.java
@@ -18,6 +18,7 @@
import com.lody.virtual.client.env.VirtualRuntime;
import com.lody.virtual.client.hook.secondary.ServiceConnectionDelegate;
import com.lody.virtual.helper.compat.ActivityManagerCompat;
+import com.lody.virtual.helper.ipcbus.IPCSingleton;
import com.lody.virtual.helper.utils.ComponentUtils;
import com.lody.virtual.os.VUserHandle;
import com.lody.virtual.remote.AppTaskInfo;
@@ -25,8 +26,7 @@
import com.lody.virtual.remote.PendingIntentData;
import com.lody.virtual.remote.PendingResultData;
import com.lody.virtual.remote.VParceledListSlice;
-import com.lody.virtual.server.IActivityManager;
-import com.lody.virtual.server.interfaces.IProcessObserver;
+import com.lody.virtual.server.interfaces.IActivityManager;
import java.util.HashMap;
import java.util.List;
@@ -42,27 +42,14 @@ public class VActivityManager {
private static final VActivityManager sAM = new VActivityManager();
private final Map mActivities = new HashMap(6);
- private IActivityManager mRemote;
+ private IPCSingleton singleton = new IPCSingleton<>(IActivityManager.class);
public static VActivityManager get() {
return sAM;
}
public IActivityManager getService() {
- if (mRemote == null ||
- (!mRemote.asBinder().isBinderAlive() && !VirtualCore.get().isVAppProcess())) {
- synchronized (VActivityManager.class) {
- final Object remote = getRemoteInterface();
- mRemote = LocalProxyUtils.genProxy(IActivityManager.class, remote);
- }
- }
- return mRemote;
- }
-
-
- private Object getRemoteInterface() {
- return IActivityManager.Stub
- .asInterface(ServiceManagerNative.getService(ServiceManagerNative.ACTIVITY));
+ return singleton.get();
}
@@ -331,14 +318,6 @@ public void killApplicationProcess(String procName, int uid) {
}
}
- public void registerProcessObserver(IProcessObserver observer) {
- try {
- getService().registerProcessObserver(observer);
- } catch (RemoteException e) {
- e.printStackTrace();
- }
- }
-
public void killAppByPkg(String pkg, int userId) {
try {
getService().killAppByPkg(pkg, userId);
@@ -347,14 +326,6 @@ public void killAppByPkg(String pkg, int userId) {
}
}
- public void unregisterProcessObserver(IProcessObserver observer) {
- try {
- getService().unregisterProcessObserver(observer);
- } catch (RemoteException e) {
- e.printStackTrace();
- }
- }
-
public void appDoneExecuting() {
try {
getService().appDoneExecuting();
diff --git a/VirtualApp/lib/src/main/java/com/lody/virtual/client/ipc/VDeviceManager.java b/VirtualApp/lib/src/main/java/com/lody/virtual/client/ipc/VDeviceManager.java
index 680037efe..4bd0cb06e 100644
--- a/VirtualApp/lib/src/main/java/com/lody/virtual/client/ipc/VDeviceManager.java
+++ b/VirtualApp/lib/src/main/java/com/lody/virtual/client/ipc/VDeviceManager.java
@@ -1,12 +1,11 @@
package com.lody.virtual.client.ipc;
-import android.os.IBinder;
import android.os.RemoteException;
-import com.lody.virtual.client.core.VirtualCore;
import com.lody.virtual.client.env.VirtualRuntime;
+import com.lody.virtual.helper.ipcbus.IPCSingleton;
import com.lody.virtual.remote.VDeviceInfo;
-import com.lody.virtual.server.IDeviceInfoManager;
+import com.lody.virtual.server.interfaces.IDeviceInfoManager;
/**
* @author Lody
@@ -15,7 +14,7 @@
public class VDeviceManager {
private static final VDeviceManager sInstance = new VDeviceManager();
- private IDeviceInfoManager mRemote;
+ private IPCSingleton singleton = new IPCSingleton<>(IDeviceInfoManager.class);
public static VDeviceManager get() {
@@ -23,27 +22,15 @@ public static VDeviceManager get() {
}
- public IDeviceInfoManager getRemote() {
- if (mRemote == null ||
- (!mRemote.asBinder().isBinderAlive() && !VirtualCore.get().isVAppProcess())) {
- synchronized (this) {
- Object remote = getRemoteInterface();
- mRemote = LocalProxyUtils.genProxy(IDeviceInfoManager.class, remote);
- }
- }
- return mRemote;
- }
-
- private Object getRemoteInterface() {
- final IBinder binder = ServiceManagerNative.getService(ServiceManagerNative.DEVICE);
- return IDeviceInfoManager.Stub.asInterface(binder);
+ public IDeviceInfoManager getService() {
+ return singleton.get();
}
public VDeviceInfo getDeviceInfo(int userId) {
try {
- return getRemote().getDeviceInfo(userId);
+ return getService().getDeviceInfo(userId);
} catch (RemoteException e) {
return VirtualRuntime.crash(e);
}
}
-}
+}
\ No newline at end of file
diff --git a/VirtualApp/lib/src/main/java/com/lody/virtual/client/ipc/VJobScheduler.java b/VirtualApp/lib/src/main/java/com/lody/virtual/client/ipc/VJobScheduler.java
index d51de1732..6d89e8506 100644
--- a/VirtualApp/lib/src/main/java/com/lody/virtual/client/ipc/VJobScheduler.java
+++ b/VirtualApp/lib/src/main/java/com/lody/virtual/client/ipc/VJobScheduler.java
@@ -1,12 +1,12 @@
package com.lody.virtual.client.ipc;
import android.app.job.JobInfo;
-import android.os.IBinder;
+import android.os.Parcelable;
import android.os.RemoteException;
-import com.lody.virtual.client.core.VirtualCore;
import com.lody.virtual.client.env.VirtualRuntime;
-import com.lody.virtual.server.IJobScheduler;
+import com.lody.virtual.helper.ipcbus.IPCSingleton;
+import com.lody.virtual.server.interfaces.IJobService;
import java.util.List;
@@ -18,31 +18,19 @@ public class VJobScheduler {
private static final VJobScheduler sInstance = new VJobScheduler();
- private IJobScheduler mRemote;
+ private IPCSingleton singleton = new IPCSingleton<>(IJobService.class);
public static VJobScheduler get() {
return sInstance;
}
- public IJobScheduler getRemote() {
- if (mRemote == null ||
- (!mRemote.asBinder().isBinderAlive() && !VirtualCore.get().isVAppProcess())) {
- synchronized (this) {
- Object remote = getRemoteInterface();
- mRemote = LocalProxyUtils.genProxy(IJobScheduler.class, remote);
- }
- }
- return mRemote;
- }
-
- private Object getRemoteInterface() {
- final IBinder binder = ServiceManagerNative.getService(ServiceManagerNative.JOB);
- return IJobScheduler.Stub.asInterface(binder);
+ public IJobService getService() {
+ return singleton.get();
}
public int schedule(JobInfo job) {
try {
- return getRemote().schedule(job);
+ return getService().schedule(job);
} catch (RemoteException e) {
return VirtualRuntime.crash(e);
}
@@ -50,7 +38,7 @@ public int schedule(JobInfo job) {
public List getAllPendingJobs() {
try {
- return getRemote().getAllPendingJobs();
+ return getService().getAllPendingJobs();
} catch (RemoteException e) {
return VirtualRuntime.crash(e);
}
@@ -58,7 +46,7 @@ public List getAllPendingJobs() {
public void cancelAll() {
try {
- getRemote().cancelAll();
+ getService().cancelAll();
} catch (RemoteException e) {
e.printStackTrace();
}
@@ -66,9 +54,30 @@ public void cancelAll() {
public void cancel(int jobId) {
try {
- getRemote().cancel(jobId);
+ getService().cancel(jobId);
} catch (RemoteException e) {
e.printStackTrace();
}
}
+
+
+ public JobInfo getPendingJob(int jobId) {
+ try {
+ return getService().getPendingJob(jobId);
+ } catch (RemoteException e) {
+ return (JobInfo) VirtualRuntime.crash(e);
+ }
+ }
+
+
+ public int enqueue(JobInfo job, Object workItem) {
+ if (workItem == null) {
+ return -1;
+ }
+ try {
+ return getService().enqueue(job, (Parcelable) workItem);
+ } catch (RemoteException e) {
+ return (Integer) VirtualRuntime.crash(e);
+ }
+ }
}
diff --git a/VirtualApp/lib/src/main/java/com/lody/virtual/client/ipc/VNotificationManager.java b/VirtualApp/lib/src/main/java/com/lody/virtual/client/ipc/VNotificationManager.java
index a1402e0c8..19cfb61b1 100644
--- a/VirtualApp/lib/src/main/java/com/lody/virtual/client/ipc/VNotificationManager.java
+++ b/VirtualApp/lib/src/main/java/com/lody/virtual/client/ipc/VNotificationManager.java
@@ -1,11 +1,11 @@
package com.lody.virtual.client.ipc;
import android.app.Notification;
-import android.os.IBinder;
import android.os.RemoteException;
import com.lody.virtual.client.core.VirtualCore;
-import com.lody.virtual.server.INotificationManager;
+import com.lody.virtual.helper.ipcbus.IPCSingleton;
+import com.lody.virtual.server.interfaces.INotificationManager;
import com.lody.virtual.server.notification.NotificationCompat;
/**
@@ -14,7 +14,7 @@
public class VNotificationManager {
private static final VNotificationManager sInstance = new VNotificationManager();
private final NotificationCompat mNotificationCompat;
- private INotificationManager mRemote;
+ private IPCSingleton singleton = new IPCSingleton<>(INotificationManager.class);
private VNotificationManager() {
mNotificationCompat = NotificationCompat.create();
@@ -25,18 +25,11 @@ public static VNotificationManager get() {
}
public INotificationManager getService() {
- if (mRemote == null ||
- (!mRemote.asBinder().isBinderAlive() && !VirtualCore.get().isVAppProcess())) {
- synchronized (VNotificationManager.class) {
- final IBinder pmBinder = ServiceManagerNative.getService(ServiceManagerNative.NOTIFICATION);
- mRemote = INotificationManager.Stub.asInterface(pmBinder);
- }
- }
- return mRemote;
+ return singleton.get();
}
public boolean dealNotification(int id, Notification notification, String packageName) {
- if(notification == null)return false;
+ if (notification == null) return false;
return VirtualCore.get().getHostPkg().equals(packageName)
|| mNotificationCompat.dealNotification(id, notification, packageName);
}
diff --git a/VirtualApp/lib/src/main/java/com/lody/virtual/client/ipc/VPackageManager.java b/VirtualApp/lib/src/main/java/com/lody/virtual/client/ipc/VPackageManager.java
index 317b0180e..2bff2d514 100644
--- a/VirtualApp/lib/src/main/java/com/lody/virtual/client/ipc/VPackageManager.java
+++ b/VirtualApp/lib/src/main/java/com/lody/virtual/client/ipc/VPackageManager.java
@@ -10,13 +10,12 @@
import android.content.pm.ProviderInfo;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
-import android.os.IBinder;
import android.os.RemoteException;
-import com.lody.virtual.client.core.VirtualCore;
import com.lody.virtual.client.env.VirtualRuntime;
+import com.lody.virtual.helper.ipcbus.IPCSingleton;
import com.lody.virtual.server.IPackageInstaller;
-import com.lody.virtual.server.IPackageManager;
+import com.lody.virtual.server.interfaces.IPackageManager;
import java.util.List;
@@ -26,31 +25,19 @@
public class VPackageManager {
private static final VPackageManager sMgr = new VPackageManager();
- private IPackageManager mRemote;
+ private IPCSingleton singleton = new IPCSingleton<>(IPackageManager.class);
public static VPackageManager get() {
return sMgr;
}
- public IPackageManager getInterface() {
- if (mRemote == null ||
- (!mRemote.asBinder().isBinderAlive() && !VirtualCore.get().isVAppProcess())) {
- synchronized (VPackageManager.class) {
- Object remote = getRemoteInterface();
- mRemote = LocalProxyUtils.genProxy(IPackageManager.class, remote);
- }
- }
- return mRemote;
- }
-
- private Object getRemoteInterface() {
- final IBinder pmBinder = ServiceManagerNative.getService(ServiceManagerNative.PACKAGE);
- return IPackageManager.Stub.asInterface(pmBinder);
+ public IPackageManager getService() {
+ return singleton.get();
}
public int checkPermission(String permName, String pkgName, int userId) {
try {
- return getInterface().checkPermission(permName, pkgName, userId);
+ return getService().checkPermission(permName, pkgName, userId);
} catch (RemoteException e) {
return VirtualRuntime.crash(e);
}
@@ -58,7 +45,7 @@ public int checkPermission(String permName, String pkgName, int userId) {
public ResolveInfo resolveService(Intent intent, String resolvedType, int flags, int userId) {
try {
- return getInterface().resolveService(intent, resolvedType, flags, userId);
+ return getService().resolveService(intent, resolvedType, flags, userId);
} catch (RemoteException e) {
return VirtualRuntime.crash(e);
}
@@ -66,7 +53,7 @@ public ResolveInfo resolveService(Intent intent, String resolvedType, int flags,
public PermissionGroupInfo getPermissionGroupInfo(String name, int flags) {
try {
- return getInterface().getPermissionGroupInfo(name, flags);
+ return getService().getPermissionGroupInfo(name, flags);
} catch (RemoteException e) {
return VirtualRuntime.crash(e);
}
@@ -75,7 +62,7 @@ public PermissionGroupInfo getPermissionGroupInfo(String name, int flags) {
public List getInstalledApplications(int flags, int userId) {
try {
// noinspection unchecked
- return getInterface().getInstalledApplications(flags, userId).getList();
+ return getService().getInstalledApplications(flags, userId).getList();
} catch (RemoteException e) {
return VirtualRuntime.crash(e);
}
@@ -83,7 +70,7 @@ public List getInstalledApplications(int flags, int userId) {
public PackageInfo getPackageInfo(String packageName, int flags, int userId) {
try {
- return getInterface().getPackageInfo(packageName, flags, userId);
+ return getService().getPackageInfo(packageName, flags, userId);
} catch (RemoteException e) {
return VirtualRuntime.crash(e);
}
@@ -91,7 +78,7 @@ public PackageInfo getPackageInfo(String packageName, int flags, int userId) {
public ResolveInfo resolveIntent(Intent intent, String resolvedType, int flags, int userId) {
try {
- return getInterface().resolveIntent(intent, resolvedType, flags, userId);
+ return getService().resolveIntent(intent, resolvedType, flags, userId);
} catch (RemoteException e) {
return VirtualRuntime.crash(e);
}
@@ -99,7 +86,7 @@ public ResolveInfo resolveIntent(Intent intent, String resolvedType, int flags,
public List queryIntentContentProviders(Intent intent, String resolvedType, int flags, int userId) {
try {
- return getInterface().queryIntentContentProviders(intent, resolvedType, flags, userId);
+ return getService().queryIntentContentProviders(intent, resolvedType, flags, userId);
} catch (RemoteException e) {
return VirtualRuntime.crash(e);
}
@@ -107,7 +94,7 @@ public List queryIntentContentProviders(Intent intent, String resol
public ActivityInfo getReceiverInfo(ComponentName componentName, int flags, int userId) {
try {
- return getInterface().getReceiverInfo(componentName, flags, userId);
+ return getService().getReceiverInfo(componentName, flags, userId);
} catch (RemoteException e) {
return VirtualRuntime.crash(e);
}
@@ -115,7 +102,7 @@ public ActivityInfo getReceiverInfo(ComponentName componentName, int flags, int
public List getInstalledPackages(int flags, int userId) {
try {
- return getInterface().getInstalledPackages(flags, userId).getList();
+ return getService().getInstalledPackages(flags, userId).getList();
} catch (RemoteException e) {
return VirtualRuntime.crash(e);
}
@@ -123,7 +110,7 @@ public List getInstalledPackages(int flags, int userId) {
public List queryPermissionsByGroup(String group, int flags) {
try {
- return getInterface().queryPermissionsByGroup(group, flags);
+ return getService().queryPermissionsByGroup(group, flags);
} catch (RemoteException e) {
return VirtualRuntime.crash(e);
}
@@ -131,7 +118,7 @@ public List queryPermissionsByGroup(String group, int flags) {
public PermissionInfo getPermissionInfo(String name, int flags) {
try {
- return getInterface().getPermissionInfo(name, flags);
+ return getService().getPermissionInfo(name, flags);
} catch (RemoteException e) {
return VirtualRuntime.crash(e);
}
@@ -139,7 +126,7 @@ public PermissionInfo getPermissionInfo(String name, int flags) {
public ActivityInfo getActivityInfo(ComponentName componentName, int flags, int userId) {
try {
- return getInterface().getActivityInfo(componentName, flags, userId);
+ return getService().getActivityInfo(componentName, flags, userId);
} catch (RemoteException e) {
return VirtualRuntime.crash(e);
}
@@ -147,7 +134,7 @@ public ActivityInfo getActivityInfo(ComponentName componentName, int flags, int
public List queryIntentReceivers(Intent intent, String resolvedType, int flags, int userId) {
try {
- return getInterface().queryIntentReceivers(intent, resolvedType, flags, userId);
+ return getService().queryIntentReceivers(intent, resolvedType, flags, userId);
} catch (RemoteException e) {
return VirtualRuntime.crash(e);
}
@@ -155,7 +142,7 @@ public List queryIntentReceivers(Intent intent, String resolvedType
public List getAllPermissionGroups(int flags) {
try {
- return getInterface().getAllPermissionGroups(flags);
+ return getService().getAllPermissionGroups(flags);
} catch (RemoteException e) {
return VirtualRuntime.crash(e);
}
@@ -163,7 +150,7 @@ public List getAllPermissionGroups(int flags) {
public List queryIntentActivities(Intent intent, String resolvedType, int flags, int userId) {
try {
- return getInterface().queryIntentActivities(intent, resolvedType, flags, userId);
+ return getService().queryIntentActivities(intent, resolvedType, flags, userId);
} catch (RemoteException e) {
return VirtualRuntime.crash(e);
}
@@ -171,7 +158,7 @@ public List queryIntentActivities(Intent intent, String resolvedTyp
public List queryIntentServices(Intent intent, String resolvedType, int flags, int userId) {
try {
- return getInterface().queryIntentServices(intent, resolvedType, flags, userId);
+ return getService().queryIntentServices(intent, resolvedType, flags, userId);
} catch (RemoteException e) {
return VirtualRuntime.crash(e);
}
@@ -179,7 +166,7 @@ public List queryIntentServices(Intent intent, String resolvedType,
public ApplicationInfo getApplicationInfo(String packageName, int flags, int userId) {
try {
- return getInterface().getApplicationInfo(packageName, flags, userId);
+ return getService().getApplicationInfo(packageName, flags, userId);
} catch (RemoteException e) {
return VirtualRuntime.crash(e);
}
@@ -187,7 +174,7 @@ public ApplicationInfo getApplicationInfo(String packageName, int flags, int use
public ProviderInfo resolveContentProvider(String name, int flags, int userId) {
try {
- return getInterface().resolveContentProvider(name, flags, userId);
+ return getService().resolveContentProvider(name, flags, userId);
} catch (RemoteException e) {
return VirtualRuntime.crash(e);
}
@@ -195,7 +182,7 @@ public ProviderInfo resolveContentProvider(String name, int flags, int userId) {
public ServiceInfo getServiceInfo(ComponentName componentName, int flags, int userId) {
try {
- return getInterface().getServiceInfo(componentName, flags, userId);
+ return getService().getServiceInfo(componentName, flags, userId);
} catch (RemoteException e) {
return VirtualRuntime.crash(e);
}
@@ -203,7 +190,7 @@ public ServiceInfo getServiceInfo(ComponentName componentName, int flags, int us
public ProviderInfo getProviderInfo(ComponentName componentName, int flags, int userId) {
try {
- return getInterface().getProviderInfo(componentName, flags, userId);
+ return getService().getProviderInfo(componentName, flags, userId);
} catch (RemoteException e) {
return VirtualRuntime.crash(e);
}
@@ -211,7 +198,7 @@ public ProviderInfo getProviderInfo(ComponentName componentName, int flags, int
public boolean activitySupportsIntent(ComponentName component, Intent intent, String resolvedType) {
try {
- return getInterface().activitySupportsIntent(component, intent, resolvedType);
+ return getService().activitySupportsIntent(component, intent, resolvedType);
} catch (RemoteException e) {
return VirtualRuntime.crash(e);
}
@@ -220,7 +207,7 @@ public boolean activitySupportsIntent(ComponentName component, Intent intent, St
public List queryContentProviders(String processName, int uid, int flags) {
try {
// noinspection unchecked
- return getInterface().queryContentProviders(processName, uid, flags).getList();
+ return getService().queryContentProviders(processName, uid, flags).getList();
} catch (RemoteException e) {
return VirtualRuntime.crash(e);
}
@@ -228,7 +215,7 @@ public List queryContentProviders(String processName, int uid, int
public List querySharedPackages(String packageName) {
try {
- return getInterface().querySharedPackages(packageName);
+ return getService().querySharedPackages(packageName);
} catch (RemoteException e) {
return VirtualRuntime.crash(e);
}
@@ -236,7 +223,7 @@ public List querySharedPackages(String packageName) {
public String[] getPackagesForUid(int uid) {
try {
- return getInterface().getPackagesForUid(uid);
+ return getService().getPackagesForUid(uid);
} catch (RemoteException e) {
return VirtualRuntime.crash(e);
}
@@ -244,7 +231,7 @@ public String[] getPackagesForUid(int uid) {
public int getPackageUid(String packageName, int userId) {
try {
- return getInterface().getPackageUid(packageName, userId);
+ return getService().getPackageUid(packageName, userId);
} catch (RemoteException e) {
return VirtualRuntime.crash(e);
}
@@ -252,7 +239,7 @@ public int getPackageUid(String packageName, int userId) {
public String getNameForUid(int uid) {
try {
- return getInterface().getNameForUid(uid);
+ return getService().getNameForUid(uid);
} catch (RemoteException e) {
return VirtualRuntime.crash(e);
}
@@ -261,7 +248,7 @@ public String getNameForUid(int uid) {
public IPackageInstaller getPackageInstaller() {
try {
- return getInterface().getPackageInstaller();
+ return IPackageInstaller.Stub.asInterface(getService().getPackageInstaller());
} catch (RemoteException e) {
return VirtualRuntime.crash(e);
}
diff --git a/VirtualApp/lib/src/main/java/com/lody/virtual/client/ipc/VirtualLocationManager.java b/VirtualApp/lib/src/main/java/com/lody/virtual/client/ipc/VirtualLocationManager.java
index e9e5393f9..98160ffce 100644
--- a/VirtualApp/lib/src/main/java/com/lody/virtual/client/ipc/VirtualLocationManager.java
+++ b/VirtualApp/lib/src/main/java/com/lody/virtual/client/ipc/VirtualLocationManager.java
@@ -1,14 +1,13 @@
package com.lody.virtual.client.ipc;
-import android.os.IBinder;
import android.os.RemoteException;
-import com.lody.virtual.client.core.VirtualCore;
import com.lody.virtual.client.env.VirtualRuntime;
import com.lody.virtual.client.hook.base.MethodProxy;
+import com.lody.virtual.helper.ipcbus.IPCSingleton;
import com.lody.virtual.remote.vloc.VCell;
import com.lody.virtual.remote.vloc.VLocation;
-import com.lody.virtual.server.IVirtualLocationManager;
+import com.lody.virtual.server.interfaces.IVirtualLocationManager;
import java.util.List;
@@ -19,7 +18,7 @@
public class VirtualLocationManager {
private static final VirtualLocationManager sInstance = new VirtualLocationManager();
- private IVirtualLocationManager mRemote;
+ private IPCSingleton singleton = new IPCSingleton<>(IVirtualLocationManager.class);
public static final int MODE_CLOSE = 0;
public static final int MODE_USE_GLOBAL = 1;
@@ -31,25 +30,14 @@ public static VirtualLocationManager get() {
}
- public IVirtualLocationManager getRemote() {
- if (mRemote == null ||
- (!mRemote.asBinder().isBinderAlive() && !VirtualCore.get().isVAppProcess())) {
- synchronized (this) {
- Object remote = getRemoteInterface();
- mRemote = LocalProxyUtils.genProxy(IVirtualLocationManager.class, remote);
- }
- }
- return mRemote;
+ public IVirtualLocationManager getService() {
+ return singleton.get();
}
- private Object getRemoteInterface() {
- final IBinder binder = ServiceManagerNative.getService(ServiceManagerNative.VIRTUAL_LOC);
- return IVirtualLocationManager.Stub.asInterface(binder);
- }
public int getMode(int userId, String pkg) {
try {
- return getRemote().getMode(userId, pkg);
+ return getService().getMode(userId, pkg);
} catch (RemoteException e) {
return VirtualRuntime.crash(e);
}
@@ -61,7 +49,7 @@ public int getMode() {
public void setMode(int userId, String pkg, int mode) {
try {
- getRemote().setMode(userId, pkg, mode);
+ getService().setMode(userId, pkg, mode);
} catch (RemoteException e) {
VirtualRuntime.crash(e);
}
@@ -69,7 +57,7 @@ public void setMode(int userId, String pkg, int mode) {
public void setCell(int userId, String pkg, VCell cell) {
try {
- getRemote().setCell(userId, pkg, cell);
+ getService().setCell(userId, pkg, cell);
} catch (RemoteException e) {
VirtualRuntime.crash(e);
}
@@ -77,7 +65,7 @@ public void setCell(int userId, String pkg, VCell cell) {
public void setAllCell(int userId, String pkg, List cell) {
try {
- getRemote().setAllCell(userId, pkg, cell);
+ getService().setAllCell(userId, pkg, cell);
} catch (RemoteException e) {
VirtualRuntime.crash(e);
}
@@ -85,7 +73,7 @@ public void setAllCell(int userId, String pkg, List cell) {
public void setNeighboringCell(int userId, String pkg, List cell) {
try {
- getRemote().setNeighboringCell(userId, pkg, cell);
+ getService().setNeighboringCell(userId, pkg, cell);
} catch (RemoteException e) {
VirtualRuntime.crash(e);
}
@@ -93,7 +81,7 @@ public void setNeighboringCell(int userId, String pkg, List cell) {
public VCell getCell(int userId, String pkg) {
try {
- return getRemote().getCell(userId, pkg);
+ return getService().getCell(userId, pkg);
} catch (RemoteException e) {
return VirtualRuntime.crash(e);
}
@@ -101,7 +89,7 @@ public VCell getCell(int userId, String pkg) {
public List getAllCell(int userId, String pkg) {
try {
- return getRemote().getAllCell(userId, pkg);
+ return getService().getAllCell(userId, pkg);
} catch (RemoteException e) {
return VirtualRuntime.crash(e);
}
@@ -109,7 +97,7 @@ public List getAllCell(int userId, String pkg) {
public List getNeighboringCell(int userId, String pkg) {
try {
- return getRemote().getNeighboringCell(userId, pkg);
+ return getService().getNeighboringCell(userId, pkg);
} catch (RemoteException e) {
return VirtualRuntime.crash(e);
}
@@ -118,7 +106,7 @@ public List getNeighboringCell(int userId, String pkg) {
public void setGlobalCell(VCell cell) {
try {
- getRemote().setGlobalCell(cell);
+ getService().setGlobalCell(cell);
} catch (RemoteException e) {
VirtualRuntime.crash(e);
}
@@ -126,7 +114,7 @@ public void setGlobalCell(VCell cell) {
public void setGlobalAllCell(List cell) {
try {
- getRemote().setGlobalAllCell(cell);
+ getService().setGlobalAllCell(cell);
} catch (RemoteException e) {
VirtualRuntime.crash(e);
}
@@ -134,7 +122,7 @@ public void setGlobalAllCell(List cell) {
public void setGlobalNeighboringCell(List cell) {
try {
- getRemote().setGlobalNeighboringCell(cell);
+ getService().setGlobalNeighboringCell(cell);
} catch (RemoteException e) {
VirtualRuntime.crash(e);
}
@@ -142,7 +130,7 @@ public void setGlobalNeighboringCell(List cell) {
public void setLocation(int userId, String pkg, VLocation loc) {
try {
- getRemote().setLocation(userId, pkg, loc);
+ getService().setLocation(userId, pkg, loc);
} catch (RemoteException e) {
VirtualRuntime.crash(e);
}
@@ -150,7 +138,7 @@ public void setLocation(int userId, String pkg, VLocation loc) {
public VLocation getLocation(int userId, String pkg) {
try {
- return getRemote().getLocation(userId, pkg);
+ return getService().getLocation(userId, pkg);
} catch (RemoteException e) {
return VirtualRuntime.crash(e);
}
@@ -162,7 +150,7 @@ public VLocation getLocation() {
public void setGlobalLocation(VLocation loc) {
try {
- getRemote().setGlobalLocation(loc);
+ getService().setGlobalLocation(loc);
} catch (RemoteException e) {
VirtualRuntime.crash(e);
}
@@ -170,7 +158,7 @@ public void setGlobalLocation(VLocation loc) {
public VLocation getGlobalLocation() {
try {
- return getRemote().getGlobalLocation();
+ return getService().getGlobalLocation();
} catch (RemoteException e) {
return VirtualRuntime.crash(e);
}
diff --git a/VirtualApp/lib/src/main/java/com/lody/virtual/client/ipc/VirtualStorageManager.java b/VirtualApp/lib/src/main/java/com/lody/virtual/client/ipc/VirtualStorageManager.java
index 58f8844ec..81d7b6b1e 100644
--- a/VirtualApp/lib/src/main/java/com/lody/virtual/client/ipc/VirtualStorageManager.java
+++ b/VirtualApp/lib/src/main/java/com/lody/virtual/client/ipc/VirtualStorageManager.java
@@ -1,12 +1,11 @@
package com.lody.virtual.client.ipc;
-import android.os.IBinder;
import android.os.RemoteException;
-import com.lody.virtual.client.core.VirtualCore;
import com.lody.virtual.client.env.VirtualRuntime;
-import com.lody.virtual.server.IVirtualStorageService;
+import com.lody.virtual.helper.ipcbus.IPCSingleton;
+import com.lody.virtual.server.interfaces.IVirtualStorageService;
/**
* @author Lody
@@ -15,7 +14,7 @@
public class VirtualStorageManager {
private static final VirtualStorageManager sInstance = new VirtualStorageManager();
- private IVirtualStorageService mRemote;
+ private IPCSingleton singleton = new IPCSingleton<>(IVirtualStorageService.class);
public static VirtualStorageManager get() {
@@ -24,19 +23,7 @@ public static VirtualStorageManager get() {
public IVirtualStorageService getRemote() {
- if (mRemote == null ||
- (!mRemote.asBinder().isBinderAlive() && !VirtualCore.get().isVAppProcess())) {
- synchronized (this) {
- Object remote = getRemoteInterface();
- mRemote = LocalProxyUtils.genProxy(IVirtualStorageService.class, remote);
- }
- }
- return mRemote;
- }
-
- private Object getRemoteInterface() {
- final IBinder binder = ServiceManagerNative.getService(ServiceManagerNative.VS);
- return IVirtualStorageService.Stub.asInterface(binder);
+ return singleton.get();
}
public void setVirtualStorage(String packageName, int userId, String vsPath) {
diff --git a/VirtualApp/lib/src/main/java/com/lody/virtual/client/stub/StubJob.java b/VirtualApp/lib/src/main/java/com/lody/virtual/client/stub/StubJob.java
index 18d87075d..113e054eb 100644
--- a/VirtualApp/lib/src/main/java/com/lody/virtual/client/stub/StubJob.java
+++ b/VirtualApp/lib/src/main/java/com/lody/virtual/client/stub/StubJob.java
@@ -12,6 +12,7 @@
import android.os.Build;
import android.os.IBinder;
import android.os.RemoteException;
+import android.util.Log;
import com.lody.virtual.client.core.InvocationStubManager;
import com.lody.virtual.client.hook.proxies.am.ActivityManagerStub;
@@ -109,6 +110,8 @@ public void onCreate() {
super.onCreate();
InvocationStubManager.getInstance().checkEnv(ActivityManagerStub.class);
mScheduler = (JobScheduler) getSystemService(JOB_SCHEDULER_SERVICE);
+
+ Log.d("Q_M", "StubJob-->onCreate");
}
@Override
diff --git a/VirtualApp/lib/src/main/java/com/lody/virtual/client/stub/VASettings.java b/VirtualApp/lib/src/main/java/com/lody/virtual/client/stub/VASettings.java
index 8c662c38d..46bc8717e 100644
--- a/VirtualApp/lib/src/main/java/com/lody/virtual/client/stub/VASettings.java
+++ b/VirtualApp/lib/src/main/java/com/lody/virtual/client/stub/VASettings.java
@@ -20,6 +20,16 @@ public class VASettings {
"com.google.android.gms"
};
+ /**
+ * 是否禁止插件应用直接调用返回桌面的 intent
+ *