Another way to bypass the hidden api restriction. - Android Apps and Games

Github: bypassHiddenApiRestriction​This is a library that can bypass the hidden api restriction from Android 9 to 12.
Usage:
dependencies {
implementation 'io.github.windysha:bypassHiddenApiRestriction:1.1.0'
}
import com.wind.hiddenapi.bypass.HiddenApiBypass
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
HiddenApiBypass.startBypass();
}

Related

[GUIDE] AutomateIt Plug-in Development

Prerequisite
Don't know what is AutomateIt ? Read more on this thread.
What is AutomateIt Plugin ?
Plugins are applications that by installing them, you add new actions and triggers that you can use within AutomateIt. Sounds easy, right ?
Each plugin can provide additional triggers and actions that extend the capabilities of AutomateIt, so you can focus on the functionality and take advantage of the AutomateIt platform to connect each trigger or action with existing capabilities of AutomateIt or with other plugins.
More details and a list of available plugins are available on the app website.
Getting started
Although developing a plugin is super-easy and requires only several simple steps, you are deeply encouraged to read the full documentation on the app website.
To summarize it for you, here are the steps you need to follow when developing a new plugin:
Download AutomateIt Plugin SDK
Setup your environment
Develop your plugin
Test your plugin
Setting up your environment after downloading the plugin SDK is done by adding a single dependency needs to be added to your build.gradle file:
Code:
compile 'com.automateitapp:automateit.plugin.sdk:1.0.3'
Creating a new plugin action or trigger is done by implementing a class that extends either PluginAction or PluginTrigger in your plugin project that references the AutomateItPluginLibrary.
Each of these abstract classes requires a set of simple functions to be implemented that provide metadata for the action or trigger (such as title, description, icons and parameters) and the functionality of the action or trigger. See sample code below for an action that shows a Toast message.
a complete sample app is available as a git repo that can be cloned from here.
When the plugin app is installed on a user device, it communicates with AutomateIt so that the plugin actions and triggers become available within AutomateIt.
Additional Documentation
AutomateIt Plugin Developer Guide
AutomateIt Plugin SDK Reference
Looking forward to seeing some awesome plugins !
Sample Action Code
Code:
package com.smarterapps.demoplugin.actions;
import java.util.List;
import android.content.Context;
import android.widget.Toast;
import com.smarterapps.automateitplugin.sdk.PluginDataFieldCollection;
import com.smarterapps.automateitplugin.sdk.PluginValidationResult;
import com.smarterapps.automateitplugin.sdk.RequiredApp;
import com.smarterapps.automateitplugin.sdk.fields.PluginDataFieldBoolean;
import com.smarterapps.automateitplugin.sdk.fields.PluginDataFieldString;
import com.smarterapps.demoplugin.R;
public class Action1 extends com.smarterapps.automateitplugin.sdk.PluginAction
{
private static final int FIELD_ID_TEXT_TO_SHOW = 1;
private static final int FIELD_ID_DURATION_LONG = 2;
@Override
public String getActionTitle(Context context)
{
return context.getString(R.string.action1_title);
}
@Override
public String getActionDescription(Context context)
{
return context.getString(R.string.action1_default_description);
}
@Override
public String getActionDescription(Context context, PluginDataFieldCollection data)
{
if (null != data)
{
String msgText = (String) data.getFieldById(FIELD_ID_TEXT_TO_SHOW).getValue();
boolean durationLong = (Boolean) data.getFieldById(FIELD_ID_DURATION_LONG).getValue();
int toastDurationStringId = durationLong ? R.string.duration_long: R.string.duration_short;
return context.getString(R.string.action1_description,
context.getString(toastDurationStringId),
msgText);
}
return getActionDescription(context);
}
@Override
public int getActionIconResourceId()
{
return R.drawable.ic_action1;
}
@Override
public int getActionSmallIconResourceId()
{
return R.drawable.ic_action1_small;
}
@Override
public PluginDataFieldCollection getActionFields(Context context)
{
PluginDataFieldCollection retval = new PluginDataFieldCollection();
retval.add(new PluginDataFieldBoolean(
FIELD_ID_DURATION_LONG,
context.getString(R.string.action1_field_duration_title),
context.getString(R.string.action1_field_duration_description),
true));
retval.add(new PluginDataFieldString(
FIELD_ID_TEXT_TO_SHOW,
context.getString(R.string.action1_field_msg_title),
context.getString(R.string.action1_field_msg_description),
""));
return retval;
}
@Override
public void doAction(Context context, PluginDataFieldCollection data)
{
boolean durationLong = (Boolean) data.getFieldById(FIELD_ID_DURATION_LONG).getValue();
int toastDuration = durationLong ? Toast.LENGTH_LONG : Toast.LENGTH_SHORT;
String toastMsg = (String) data.getFieldById(FIELD_ID_TEXT_TO_SHOW).getValue();
Toast.makeText(context, toastMsg, toastDuration).show();
}
@Override
public PluginValidationResult validateData(Context context, PluginDataFieldCollection data)
{
// Validate action1
String toastMsg = (String) data.getFieldById(FIELD_ID_TEXT_TO_SHOW).getValue();
if (null == toastMsg || toastMsg.trim().length() == 0)
{
return new PluginValidationResult(false, "Toast message can't be empty");
}
return PluginValidationResult.getValidResult();
}
@Override
public List<RequiredApp> getRequiredApps()
{
return null;
}
}
AutomateIt Plugin SDK has been updated so it is now even easier to integrate actions and triggers into your apps, or build a brand new plugin.
It requires a single dependency in your build.gradle file and the rest is up to you!
Sample app is available as a git repo on bitbucket.org:
https://bitbucket.org/AutomateIt/automateit-plugin-demo
(Instructions were updated on the developer website and this post).

Google Play Game Services in libgdx

The article was written in the course of the game's development CLEAR SKY 2
The first part here!
Code
In the main Activity implement two interfaces GameHelperListener, ActionResolver:
public class MainActivity extends AndroidApplication implements GameHelperListener, ActionResolver
GameHelperListener interface is as follows:
Code:
public interface GameHelperListener {
/ **
* Called when an attempt to login. This method can show
* User button «Sign-in» for manual entry
* /
void onSignInFailed ();
/ ** Called when a successful login attempt * /
void onSignInSucceeded ();
}
Interface ActionResolver create ourselves. He needed to call the platform-dependent code. This technique is described in the official wiki libgdx. An example of the interface:
Code:
public interface ActionResolver {
/ ** Check the status of the user input * /
public boolean getSignedInGPGS ();
/ ** Log * /
public void loginGPGS ();
/ ** Send the result in the high score table * /
public void submitScoreGPGS (int score);
/ **
* Unlock achievement
*
*param AchievementId
* ID achievements. Taken from the file games-ids.xml
* /
public void unlockAchievementGPGS (String achievementId);
/ ** Show Activity records to the table * /
public void getLeaderboardGPGS ();
/ ** Show Activity achievements * /
public void getAchievementsGPGS ();
}
Example code main Activity:
Code:
public class MainActivity extends AndroidApplication implements
GameHelperListener, ActionResolver {
// Assistant to work with gaming services
private GameHelper gameHelper;
// Class of our games
private TestGame game;
Override
public void onCreate (Bundle savedInstanceState) {
super.onCreate (savedInstanceState);
// CLIENT_ALL instruct you on the use of the API all customers
gameHelper = new GameHelper (this, GameHelper.CLIENT_ALL);
// Disable automatic login when starting the game
gameHelper.setConnectOnStart (false);
gameHelper.enableDebugLog (true);
// From turning off the screen without the use of additional
// Permits (less than permissions - more confidence in the application)
getWindow (). addFlags (WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
// Input parameter this is ActionResolver. Allows you to call from
// Game loop platform-specific methods GPGS
game = new TestGame (this);
AndroidApplicationConfiguration config = new AndroidApplicationConfiguration ();
initialize (game, config);
gameHelper.setup (this);
}
// Methods gameHelper'a: onStart (), onStop () are called to work correctly
// GPGS in the lifecycle of android-app
Override
protected void onStart () {
super.onStart ();
gameHelper.onStart (this);
}
Override
protected void onStop () {
super.onStop ();
gameHelper.onStop ();
}
Override
protected void onDestroy () {
super.onDestroy ();
}
Override
protected void onActivityResult (int requestCode, int resultCode, Intent data) {
super.onActivityResult (requestCode, resultCode, data);
// Here gameHelper decides to connect, or reconnect
// Disconnected from the game services, depending on the result code
// Activity
gameHelper.onActivityResult (requestCode, resultCode, data);
}
Override
public boolean getSignedInGPGS () {
// Connection status
return gameHelper.isSignedIn ();
}
Override
public void loginGPGS () {
try {
runOnUiThread (new Runnable () {
Override
public void run () {
// Initiate user entry. Can be called a dialogue
// Login. Performed in UI-stream
gameHelper.beginUserInitiatedSignIn ();
}
});
} Catch (Exception e) {
e.printStackTrace ();
}
}
Override
public void submitScoreGPGS (int score) {
// Send game points to a specific table records with ID
// "HgkIr62KmoQJEAIQAQ"
Games.Leaderboards.submitScore (gameHelper.getApiClient (),
"HgkIr62KmoQJEAIQAQ", score);
}
Override
public void unlockAchievementGPGS (String achievementId) {
// Open achievement with ID achievementId
Games.Achievements.unlock (gameHelper.getApiClient (), achievementId);
}
Override
public void getLeaderboardGPGS () {
Activity // call for all registered tables records. as
Activity // can call for a specific table
startActivityForResult (
Games.Leaderboards.getAllLeaderboardsIntent (gameHelper
.getApiClient ()), 100);
}
Override
public void getAchievementsGPGS () {
// Call Activity achievements
startActivityForResult (
Games.Achievements.getAchievementsIntent (gameHelper
.getApiClient ()), 101);
}
Override
public void onSignInSucceeded () {
}
Override
public void onSignInFailed () {
}
}
Suppose we have in the game provided the achievement - to collect 1 million. Player points, the code implementing it would look like this:
Code:
public static void checkTotalPoints (int points) {
ActionResolver res = getActionResolver ();
if (! res.getSignedInGPGS ()) {
return;
}
if (points> = 1000000) {
res.unlockAchievementGPGS ("HgkIr62KmoQJEAIQGA");
}
}
Same thing with a table of records, only even easier: you just need to call the submitScoreGPGS (int score) interface ActionResolver.
PS To test gaming services need to export apk-file with the same certificate as in the developer console. Just need to add accounts testers in the console. Changes in gaming services come into effect after a while.
Google Play Clear Sky 2
Long second part released!
sources used
developers.google.com/games/services/android/quickstart
developer.android.com/intl/ru/google/play-services/setup.html
github.com/libgdx/libgdx/wiki
Please don't add the &hl=ru parameter to your Play Store links - then it is in Russian for all users. Without it, native language is used.

Automatically post test results in JIRA Adaptavist Tool from rest api test cases run

I need some guidance for recording Test Results Automatically in JIRA Adaptavist Test Management Tool using Java and Testng or any other method within the framework of Java. my automation test cases are in JIRA Adaptavist Test Management Tool. The test cases are written in Java & TestNg and are running on a VM. Our Android team developed some code to deal with this problem. It is just that I don't know how to solve this. they used kotlin to build the code mapping the automation test case names to that of the TestIDs in JIRA Adaptavist Test Management Tool.
Every time we run the automation, the team has to input the results in JIRA Adaptavist Test Management Tool manually. It is becoming cumbersome for us to deal with this.
Here is the android team's code :
Open class rTestCaseHelper {
@Rule
@jvmField
val grantWriteStorageAccess: GrantPermissionRule = GrantPermissionRule.grant(
android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
@Rule
@jvmField
val reportRule :TestWatcher = Object : TestWatcher() {
var startTime = 0
override fun starting(description: Description?) {
startTime = System.currentTimeMillis().toInt()
if (sharedPreference.getTestCount() == 0) {
testManager.getTestIdAndStoreToSharedPreference()
testManager.createTestCycle()
}
}
override fun succeeded(description: Description?) {
if(description != null) {
val executionTime = System.currentTimeMillis().toInt() - startTime
testManager.generateExecutionReport(description.methodName, result: "Pass", executionTime)
}
}
override fun failed(e: Throwable?, description: Description?) {
super.failed(e.description)
if(description != null) {
val executionTime = System.currentTimeMillis().toInt() - startTime
testManager.generateExecutionReport(description.methodName, result: "Fail", executionTime, e)
}
}
override fun finished(description: Description?) {
sharedPreference.setTestCount(sharedPreference.getTestCount() -1)
//Post artfact report link to test cycle (TODO)
testManager.postWebLinkToTestCycle()
rSharedPreference.preference.edit().clear()
Log.d(tag: "QAA", msg: "Automation suite finished and sharedPreference data is cleared!")
}
}
}
fun initializeSDK(activeProtection: Boolean = false): Boolean {
rSdkEnvironment.initializeSDK(activeProtection, InstrumentationRegistry.getInstrumentation().targetContext)
return rSdk.isInitialized()
}

Integrating SysIntegrity to Check Whether Devices Running Your App are Secure

Overview
In the previous post, we learned how to integrate the UserDetect API in Safety Detect into your app to identify fake users. I've been glad to receive so much positive feedback. In this post, I'll introduce SysIntegrity (system integrity check), yet another handy function in Safety Detect. Apps can face malicious attacks when they run on insecure devices, for example, rooted devices. For certain apps, such as e-commerce apps, ensuring a secure running environment during user transactions is particularly crucial. SysIntegrity enables apps to do so by helping detect device system-related risks in advance.
I encountered this function on the HUAWEI Developers website. SysIntegrity works by integrating the Safety Detect SDK into your app, and calling the SysIntegrity API in Safety Detect. It performs the check within a Trusted Execution Environment (TEE) and signs the check result with an X.509 digital certificate to ensure that it is trustworthy and tamperproof.
Now let's take a look at what it's like in practice.
{
"lightbox_close": "Close",
"lightbox_next": "Next",
"lightbox_previous": "Previous",
"lightbox_error": "The requested content cannot be loaded. Please try again later.",
"lightbox_start_slideshow": "Start slideshow",
"lightbox_stop_slideshow": "Stop slideshow",
"lightbox_full_screen": "Full screen",
"lightbox_thumbnails": "Thumbnails",
"lightbox_download": "Download",
"lightbox_share": "Share",
"lightbox_zoom": "Zoom",
"lightbox_new_window": "New window",
"lightbox_toggle_sidebar": "Toggle sidebar"
}
Next, I'll show you how to integrate SysIntegrity.
Content
1 Preparations
1.1 Installing Android studio
1.2 Configuring App Information in AppGallery Connect
1.3 Configuring the Huawei Maven Repository Address
1.4 Adding Build Dependencies
1.5 Configuring Obfuscation Scripts
2 Code Development
2.1 Creating a SafetyDetectClient Instance and Generating a Nonce
2.2 Calling the SysIntegrity API
2.3 Verifying the Check Result on the App Server
2.4 Obtaining the System Integrity Check Result
1. Preparations
1.1 Installing Android Studio
To install Android Studio, please refer to the following:
l Android Studio Official Website
l Android Studio Installation and Configuration
1.2 Configuring App Information in AppGallery Connect
Before developing an app, you'll need to configure the app information in AppGallery Connect. For more details, please refer to Preparations.
1.3 Configuring the Huawei Maven Repository Address
Open the build.gradle file in the root directory of your Android Studio project.
Add the AppGallery Connect plug-in and the Maven repository address.
(1) Go to buildscript > repositories and configure the Maven repository address for the HMS Core SDK.
(2) Go to allprojects > repositories and configure the Maven repository address for the HMS Core SDK.
(3) If the agconnect-services.json file has been added to the app, go to buildscript > dependencies and add the AppGallery Connect plug-in configuration.
XML:
<p style="line-height: 1.5em;">apply plugin: 'com.huawei.agconnect'
</p>
Add the build dependency in the dependencies section.
XML:
<p style="line-height: 1.5em;">dependencies {
implementation 'com.huawei.hms:safetydetect:5.0.5.302'
}
</p>
1.5 Configuring Obfuscation Scripts
If you are using AndResGuard, add its trustlist to the build.gradle file in the app directory of your project. For more details about the code, please refer to Configuring Obfuscation Scripts on the HUAWEI Developers website.
2. Code Development
2.1 Creating a SafetyDetectClient Instance and Generating a Nonce
The nonce value will be contained in the check result. You can check the nonce value to verify that the returned result corresponds to your request, and does not encounter replay attacks. A nonce value should:
l Be used only once.
l Contain 16 to 66 bytes.
l Be derived from data sent to your server (Recommended).
2.2 Calling the SysIntegrity API
(1) The SysIntegrity API has two input parameters: the nonce value (obtained during the previous step) and your app ID. You can obtain the app ID from the agconnect-services.jsonfile under the app directory of your project.
Ø Sign in to AppGallery Connect and click My projects.
Ø Find your app project and click the desired app name.
Ø Go to Project Setting > General information, and view the app ID in the App information area.
Java:
<p style="line-height: 1.5em;">private void onAdapterItemClick(int position) {
// Call the SysIntegrity API to check for risks in the payment environment.
SafetyDetectUtil.detectSysIntegrity(this, new ICallBack<Boolean>() {
@Override
public void onSuccess(Boolean baseIntegrity) {
if (baseIntegrity) {
// The system integrity is not corrupted, and the user can proceed with the purchase.
buy(productInfo);
} else {
// The system integrity is corrupted. A popup is displayed to warn the user and ask the user whether to continue.
showRootTipDialog(productInfo);
}
}
…
});
}
</p>
(3) In my app, I encapsulated the SysIntegrity API in the detectSysIntegrity method of the SafetyDetectUtil.java class. The sample code is as follows:
Java:
<p style="line-height: 1.5em;">public static void detectSysIntegrity(final Activity activity, final ICallBack<? super Boolean> callBack) {
// Generate a nonce value.
byte[] nonce = ("Sample" + System.currentTimeMillis()).getBytes(StandardCharsets.UTF_8);
// Read the app_id field from the agconnect-services.json file in the app directory.
String appId = AGConnectServicesConfig.fromContext(activity).getString("client/app_id");
// Obtain the Safety Detect client, call the SysIntegrity API, and add a success event listener.
SysIntegrityRequest sysintegrityrequest = new SysIntegrityRequest();
sysintegrityrequest.setAppid(appId);
sysintegrityrequest.setNonce(nonce);
// PS256 or RS256
sysintegrityrequest.setAlg("RS256");
Task task = mClient.sysIntegrity(sysintegrityrequest);
task.addOnSuccessListener(new OnSuccessListener<SysIntegrityResp>() {
@Override
public void onSuccess(SysIntegrityResp response) {
// Call the getResult method of the SysIntegrityResp class to obtain the check result.
String jwsStr = response.getResult();
VerifyResultHandler verifyResultHandler = new VerifyResultHandler(jwsStr, callBack);
// Send the check result to your server for verification.
verifyJws(activity, jwsStr, verifyResultHandler);
}
});
}
</p>
(4) Here, I called the relevant app server API in the verifyJws method to verify the check result. The third parameter in this method is an object of the VerifyResultHandler class, which implements a callback API to process the verification result.
2.3 Verifying the Check Result on the App Server
After receiving the check result from the TSMS server, the app will send the result to the app server. The server uses the HUAWEI CBG Root CA certificate to verify the signature and certificate chain in the check result, and thereby determines whether the check result is valid.
The sample code for the app server to read the certificate and verify the JWS string is as follows:
(1) Parse the header, payload, and signature from the JWS string.
Java:
<p style="line-height: 1.5em;">public JwsVerifyResp verifyJws(JwsVerifyReq jwsVerifyReq) {
// Obtain the JWS information sent from the app to the server.
String jwsStr = jwsVerifyReq.getJws();
// Parse the JWS segments. A JWS has three fixed segments, which are separated by periods (.).
String[] jwsSplit = jwsStr.split("\\.");
try {
// Perform Base64 decoding on each segment and construct a JWS object for each decoded segment.
JWSObject jwsObject = new JWSObject(new Base64URL(jwsSplit[0]), new Base64URL(jwsSplit[1]), new Base64URL(jwsSplit[2]));
// Verify the JWS and set the verification result.
boolean result = VerifySignatureUtil.verifySignature(jwsObject);
// Construct the response body for check result verification on the app server.
JwsVerifyResp jwsVerifyResp = new JwsVerifyResp();
jwsVerifyResp.setResult(result);
} catch (ParseException | NoSuchAlgorithmException e) {
RUN_LOG.catching(e);
}
return jwsVerifyResp;
}
</p>
(2) Use the verifySignature method of the VerifySignatureUtil class to verify relevant information, including the JWS signature algorithm, certificate chain, host name in signing certificate, and JWS signature. The sample code is as follows:
Java:
<p style="line-height: 1.5em;">public static boolean verifySignature(JWSObject jws) throws NoSuchAlgorithmException {
JWSAlgorithm jwsAlgorithm = jws.getHeader().getAlgorithm();
// 1. Verify the JWS signature algorithm.
if ("RS256".equals(jwsAlgorithm.getName())) {
// Verify the certificate chain and obtain an instance of the Signature class based on the signature algorithm to verify the signature.
return verify(Signature.getInstance("SHA256withRSA"), jws);
}
return false;
}
private static boolean verify(Signature signature, JWSObject jws) {
// Extract the certificate chain information from the JWS header and convert the certificate chain into a proper type for subsequent processing.
X509Certificate[] certs = extractX509CertChain(jws);
// 2. Verify the certificate chain.
try {
verifyCertChain(certs);
} catch (Exception e) {
return false;
}
// 3. Verify the domain name in the signing certificate (leaf certificate). The domain name must be sysintegrity.platform.hicloud.com.
try {
new DefaultHostnameVerifier().verify("sysintegrity.platform.hicloud.com", certs[0]);
} catch (SSLException e) {
return false;
}
// 4. Verify the JWS signature information using the public key obtained from the signing certificate.
PublicKey pubKey = certs[0].getPublicKey();
try {
// Use the public key obtained from the signing certificate to initialize the Signature instance.
signature.initVerify(pubKey);
// Extract the input signature from the JWS and pass it to the Signature instance.
signature.update(jws.getSigningInput());
// Use the Signature instance to verify the signature information.
return signature.verify(jws.getSignature().decode());
} catch (InvalidKeyException | SignatureException e) {
return false;
}
}
</p>
(3) Call the extractX509CertChain method to extract the certificate chain from the JWS header. The sample code is as follows:
Java:
<p style="line-height: 1.5em;">private static X509Certificate[] extractX509CertChain(JWSObject jws) {
List<X509Certificate> certs = new ArrayList<>();
List<com.nimbusds.jose.util.Base64> x509CertChain = jws.getHeader().getX509CertChain();
try {
CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
certs.addAll(x509CertChain.stream().map(cert -> {
try {
return (X509Certificate) certFactory.generateCertificate( new ByteArrayInputStream(cert.decode()) );
} catch (CertificateException e) {
RUN_LOG.error("X5c extract failed!");
}
return null;
}).filter(Objects::nonNull).collect(Collectors.toList()));
} catch (CertificateException e) {
RUN_LOG.error("X5c extract failed!");
}
return (X509Certificate[]) certs.toArray();
}
</p>
(4) Call the verifyCertChain method to verify the certificate chain. The sample code is as follows:
Java:
<p style="line-height: 1.5em;">private static void verifyCertChain(X509Certificate[] certs) throws CertificateException, NoSuchAlgorithmException,
InvalidKeyException, NoSuchProviderException, SignatureException {
// Verify the validity period and issuing relationship of each certificate one by one.
for (int i = 0; i < certs.length - 1; ++i) {
certs[i].checkValidity();
PublicKey pubKey = certs[i + 1].getPublicKey();
certs[i].verify(pubKey);
}
// Use the preset HUAWEI CBG Root CA certificate to verify the last certificate in the certificate chain.
PublicKey caPubKey = huaweiCbgRootCaCert.getPublicKey();
certs[certs.length - 1].verify(caPubKey);
}
</p>
(5) Load the HUAWEI CBG Root CA certificate in the static code snippet of the VerifySignatureUtil class. The sample code is as follows:
Java:
<p style="line-height: 1.5em;">static {
// Load the preset HUAWEI CBG Root CA certificate.
File filepath = "~/certs/Huawei_cbg_root.cer";
try (FileInputStream in = new FileInputStream(filepath)) {
CertificateFactory cf = CertificateFactory.getInstance("X.509");
huaweiCbgRootCaCert = (X509Certificate) cf.generateCertificate(in);
} catch (IOException | CertificateException e) {
RUN_LOG.error("HUAWEI CBG root cert load failed!");
}
}
</p>
We have now verified the check result on the app server, and the verification result will be returned to the app for subsequent service processing.
2.4 Obtaining the System Integrity Check Result
(1) Once you complete the steps above, the app will obtain the reliable system integrity check result from the payload of the JWS string. Parse the system integrity check result from the callback API of the VerifyResultHandler class as follows:
Java:
<p style="line-height: 1.5em;">private static final class VerifyResultHandler implements ICallBack<Boolean> {
private final String jwsStr;
private final ICallBack<? super Boolean> callBack;
private VerifyResultHandler(String jwsStr, ICallBack<? super Boolean> callBack) {
this.jwsStr = jwsStr;
this.callBack = callBack;
}
@Override
public void onSuccess(Boolean verified) {
if (verified) {
// Extract the system integrity check result that has been successfully verified by the app server.
String payloadDetail = new String(Base64.decode(jwsStr.split("\\.")[1].getBytes(StandardCharsets.UTF_8), Base64.URL_SAFE), StandardCharsets.UTF_8);
try {
final boolean basicIntegrity = new JSONObject(payloadDetail).getBoolean("basicIntegrity");
// Call back the system integrity check result.
callBack.onSuccess(basicIntegrity);
} catch (JSONException e) {
…
}
}
…
}
}
</p>
(2) The following is an example of the system integrity check response:
XML:
<p style="line-height: 1.5em;">{
"apkCertificateDigestSha256": [
"osaUtTsdAvezjQBaW3IhN3/fsc6NQ5KwKuAQXcfrxb4="
],
"apkDigestSha256": "vFcmE0uw5s+4tFjXF9rVycxk2xR1rXiZFHuuBFzTVy8=",
"apkPackageName": "com.example.mockthirdapp",
"basicIntegrity": false,
"detail": [
"root",
"unlocked"
],
"nonce": "UjJScmEyNGZWbTV4YTJNZw==",
"timestampMs": 1604048377137,
"advice": "RESTORE_TO_FACTORY_ROM"
}
</p>
(3) If the value of the basicIntegrity field in the check result is false, it means that the system integrity is corrupted. In this case, the app can notify the user of any potential risks.
Conclusion
You can complete the integration by referring to the Preparations on HUAWEI Developers website. Also, you can download the SysIntegrity sample code for both Java and Kotlin from the site. And the sample code for four other functions in addition to SysIntegrity is also provided on the site.
Here is the sample code I wrote for my app. Feel free to take a look for yourself!
My sample code

Question Trying to make Viper4Android work (S908E)

Hi. I have a S908E (rooted snapdragon) and I'm trying for more than a week, nonstop, to make Viper4Android work in my device. It keepa asking for drivers everytime I open the app.
At first, I tried every post that I could find where people said that it worked. That includes several modules and V4A apps/zip, like: Audio Modification Library, JamesDSP, Audio Compatibility Patch, Viper4AndroidFX app, V4A 2.7.2.1, Shadowstep fix. And some other .zip fixes to flash via magisk.
Always removing every audio module and uninstalling V4A for each try. Got no result, Viper4Android still asks for drivers.
So, I realised that to get it to work, i need to know what exactly is the source of the problem in my phone and how to fix it.
With help of other users, I got to know a bit more about v4a and its files.
It seems the main files are audio_effects.xml and audio_effects.conf.
The folders that has the .xml file are vendor/etc and vendor/etc/audio/sku_taro. System/vendor is the same as vendor/
Ok, I noticed that my files inside sku_taro didn't had any line related to v4a. So I got those files from vendor/etc and copied them inside sku_taro (via magisk, since I can't edit files there). Didn't work.
I noticed another issue: audio_effects.conf isn't modified to V4A and I'm not sure if it should. The V4A system folder in data/adb/modules/ doesn't have this .conf file. However, my S21+ (exynos) that had v4a working had this file with v4a lines.
So, my first question to keep going in this odyssey is: should audio_effects.conf be modified with V4A lines and should it be present in vendor/etc as well?
EDIT: Also, what should it have modified?
It isn't the same code as in my S21+ (tried that already).
If prints of the codes of the files or the content of foldera are needed, I can post here.
No one? Come on, let's make this amazing module work in our Snapdragons!
Ok, I'm sharing my audio_effects.conf files, in the case someone who understand better than me to give opinions.
This is the file that i got from a S21+ (Exynos) with working V4A:
Spoiler
libraries {
v4a_fx {
path /vendor/lib/soundfx/libv4a_fx.so
}
soundbooster_plus {
path /system/lib/libsamsungSoundbooster_plus_legacy.so
}
soundalive_sec {
path /system/lib/libaudiosaplus_sec_legacy.so
}
mysound {
path /system/lib/libmysound_legacy.so
}
dap {
path /system/lib/libswdap_legacy.so
}
tdm {
path /system/lib/libsamsungSoundbooster_tdm_legacy.so
}
volumemonitor {
path /system/lib/libvolumemonitor_energy.so
}
voicechanger {
path /system/lib/libvoicechanger.so
}
dht {
path /system/lib/libswdht_legacy.so
}
}
effects {
v4a_standard_fx {
library v4a_fx
uuid 41d3c987-e6cf-11e3-a88a-11aba5d5c51b
}
soundbooster_plus {
library soundbooster_plus
uuid 50de45f0-5d4c-11e5-a837-0800200c9a66
}
soundalive {
library soundalive_sec
uuid cf65eb39-ce2f-48a8-a903-ceb818c06745
}
dha {
library mysound
uuid 263a88e0-50b1-11e2-bcfd-0800200c9a66
}
dolby {
library dap
uuid 6ab06da4-c516-4611-8166-452799218539
}
dlb_ht {
library dht
uuid b247dfc9-2832-4486-92c0-2db27a3785f5
}
tdm {
library tdm
uuid beb1d058-916a-4adf-9cfe-54ee5ba8c4a5
}
volumemonitor {
library volumemonitor
uuid 16311c29-bb53-4415-b7af-ae653e812de8
}
voicechanger {
library voicechanger
uuid 25c30101-9542-451f-a064-c3198e187dfc
}
}
And this is the audio_effects.conf that was present in my S22U (Snapdragon) inside vendor/etc/audio/sku_taro:
I added the V4A lines marked (Bolded,underlined and red), with the same code from the file that were inside the S21+ (the file was named audio_effects_common.conf in Exynos, I renamed to audio_effects.conf before pasting in the S22U) file, and pasted the file inside vendor/etc as well, but got no luck:
Spoiler
# List of effect libraries to load. Each library element must contain a "path" element
# giving the full path of the library .so file.
# libraries {
# <lib name> {
# path <lib path>
# }
# }
libraries {
v4a_fx {
path /vendor/lib/soundfx/libv4a_fx.so
}
bundle {
path /vendor/lib/soundfx/libbundlewrapper.so
}
reverb {
path /vendor/lib/soundfx/libreverbwrapper.so
}
qcbassboost {
path /vendor/lib/soundfx/libqcbassboost.so
}
qcvirt {
path /vendor/lib/soundfx/libqcvirt.so
}
qcreverb {
path /vendor/lib/soundfx/libqcreverb.so
}
visualizer_sw {
path /vendor/lib/soundfx/libvisualizer.so
}
visualizer_hw {
path /vendor/lib/soundfx/libqcomvisualizer.so
}
downmix {
path /vendor/lib/soundfx/libdownmix.so
}
loudness_enhancer {
path /vendor/lib/soundfx/libldnhncr.so
}
dynamics_processing {
path /vendor/lib/soundfx/libdynproc.so
}
proxy {
path /vendor/lib/soundfx/libeffectproxy.so
}
offload_bundle {
path /vendor/lib/soundfx/libqcompostprocbundle.so
}
audio_pre_processing {
path /vendor/lib/soundfx/libqcomvoiceprocessing.so
}
volume_listener {
path /vendor/lib/soundfx/libvolumelistener.so
}
audiosphere {
path /vendor/lib/soundfx/libasphere.so
}
}
# Default pre-processing library. Add to audio_effect.conf "libraries" section if
# audio HAL implements support for default software audio pre-processing effects
#
# pre_processing {
# path /vendor/lib/soundfx/libaudiopreprocessing.so
# }
# list of effects to load. Each effect element must contain a "library" and a "uuid" element.
# The value of the "library" element must correspond to the name of one library element in the
# "libraries" element.
# The name of the effect element is indicative, only the value of the "uuid" element
# designates the effect.
# The uuid is the implementation specific UUID as specified by the effect vendor. This is not the
# generic effect type UUID.
# effects {
# <fx name> {
# library <lib name>
# uuid <effect uuid>
# }
# ...
# }
effects {
# additions for the proxy implementation
# Proxy implementation
#effectname {
#library proxy
#uuid xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
# SW implemetation of the effect. Added as a node under the proxy to
# indicate this as a sub effect.
#libsw {
#library libSW
#uuid yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy
#} End of SW effect
# HW implementation of the effect. Added as a node under the proxy to
# indicate this as a sub effect.
#libhw {
#library libHW
#uuid zzzzzzzz-zzzz-zzzz-zzzz-zzzzzzzzzzzz
#}End of HW effect
#} End of effect proxy
v4a_standard_fx {
library v4a_fx
uuid 41d3c987-e6cf-11e3-a88a-11aba5d5c51b
}
bassboost {
library proxy
uuid 14804144-a5ee-4d24-aa88-0002a5d5c51b
libsw {
library qcbassboost
uuid 23aca180-44bd-11e2-bcfd-0800200c9a66
}
libhw {
library offload_bundle
uuid 2c4a8c24-1581-487f-94f6-0002a5d5c51b
}
}
virtualizer {
library proxy
uuid d3467faa-acc7-4d34-acaf-0002a5d5c51b
libsw {
library qcvirt
uuid e6c98a16-22a3-11e2-b87b-f23c91aec05e
}
libhw {
library offload_bundle
uuid 509a4498-561a-4bea-b3b1-0002a5d5c51b
}
}
equalizer {
library proxy
uuid c8e70ecd-48ca-456e-8a4f-0002a5d5c51b
libsw {
library bundle
uuid ce772f20-847d-11df-bb17-0002a5d5c51b
}
libhw {
library offload_bundle
uuid a0dac280-401c-11e3-9379-0002a5d5c51b
}
}
volume {
library bundle
uuid 119341a0-8469-11df-81f9-0002a5d5c51b
}
reverb_env_aux {
library proxy
uuid 48404ac9-d202-4ccc-bf84-0002a5d5c51b
libsw {
library qcreverb
uuid a8c1e5f3-293d-43cd-95ec-d5e26c02e217
}
libhw {
library offload_bundle
uuid 79a18026-18fd-4185-8233-0002a5d5c51b
}
}
reverb_env_ins {
library proxy
uuid b707403a-a1c1-4291-9573-0002a5d5c51b
libsw {
library qcreverb
uuid 791fff8b-8129-4655-83a4-59bc61034c3a
}
libhw {
library offload_bundle
uuid eb64ea04-973b-43d2-8f5e-0002a5d5c51b
}
}
reverb_pre_aux {
library proxy
uuid 1b78f587-6d1c-422e-8b84-0002a5d5c51b
libsw {
library qcreverb
uuid 53ef1db5-c0c0-445b-b060-e34d20ebb70a
}
libhw {
library offload_bundle
uuid 6987be09-b142-4b41-9056-0002a5d5c51b
}
}
reverb_pre_ins {
library proxy
uuid f3e178d2-ebcb-408e-8357-0002a5d5c51b
libsw {
library qcreverb
uuid b08a0e38-22a5-11e2-b87b-f23c91aec05e
}
libhw {
library offload_bundle
uuid aa2bebf6-47cf-4613-9bca-0002a5d5c51b
}
}
visualizer {
library proxy
uuid 1d0a1a53-7d5d-48f2-8e71-27fbd10d842c
libsw {
library visualizer_sw
uuid d069d9e0-8329-11df-9168-0002a5d5c51b
}
libhw {
library visualizer_hw
uuid 7a8044a0-1a71-11e3-a184-0002a5d5c51b
}
}
downmix {
library downmix
uuid 93f04452-e4fe-41cc-91f9-e475b6d1d69f
}
hw_acc {
library offload_bundle
uuid 7d1580bd-297f-4683-9239-e475b6d1d69f
}
loudness_enhancer {
library loudness_enhancer
uuid fa415329-2034-4bea-b5dc-5b381c8d1e2c
}
dynamics_processing {
library dynamics_processing
uuid e0e6539b-1781-7261-676f-6d7573696340
}
aec {
library audio_pre_processing
uuid 0f8d0d2a-59e5-45fe-b6e4-248c8a799109
}
ns {
library audio_pre_processing
uuid 1d97bb0b-9e2f-4403-9ae3-58c2554306f8
}
music_helper {
library volume_listener
uuid 08b8b058-0590-11e5-ac71-0025b32654a0
}
ring_helper {
library volume_listener
uuid 0956df94-0590-11e5-bdbe-0025b32654a0
}
alarm_helper {
library volume_listener
uuid 09f303e2-0590-11e5-8fdb-0025b32654a0
}
# voice_helper is called when stream type is voice_call in VoIP usecase
voice_helper {
library volume_listener
uuid 0ace5c08-0590-11e5-ae9e-0025b32654a0
}
notification_helper {
library volume_listener
uuid 0b776dde-0590-11e5-81ba-0025b32654a0
}
audiosphere {
library audiosphere
uuid 184e62ab-2d19-4364-9d1b-c0a40733866c
}
}
# additional effect from vendor
# UUID generated using version 1
output_session_processing {
music {
music_helper {
}
}
ring {
ring_helper {
}
}
alarm {
alarm_helper {
}
}
# stream type voice_call is used for VoIP call
voice_call {
voice_helper {
}
}
notification {
notification_helper {
}
}
}
# Added aec, ns effects for voice_communication, which are supported by the board
pre_processing {
voice_communication {
aec {
}
ns {
}
}
}
# Default pre-processing effects. Add to audio_effect.conf "effects" section if
# audio HAL implements support for them.
#
# agc {
# library pre_processing
# uuid aa8130e0-66fc-11e0-bad0-0002a5d5c51b
# }
# aec {
# library pre_processing
# uuid bb392ec0-8d4d-11e0-a896-0002a5d5c51b
# }
# ns {
# library pre_processing
# uuid c06c8400-8e06-11e0-9cb6-0002a5d5c51b
# }
# Audio preprocessor configurations.
# The pre processor configuration consists in a list of elements each describing
# pre processor settings for a given input source. Valid input source names are:
# "mic", "camcorder", "voice_recognition", "voice_communication"
# Each input source element contains a list of effects elements. The name of the effect
# element must be the name of one of the effects in the "effects" list of the file.
# Each effect element may optionally contain a list of parameters and their
# default value to apply when the pre processor effect is created.
# A parameter is defined by a "param" element and a "value" element. Each of these elements
# consists in one or more elements specifying a type followed by a value.
# The types defined are: "int", "short", "float", "bool" and "string"
# When both "param" and "value" are a single int, a simple form is allowed where just
# the param and value pair is present in the parameter description
# pre_processing {
# <input source name> {
# <fx name> {
# <param 1 name> {
# param {
# int|short|float|bool|string <value>
# [ int|short|float|bool|string <value> ]
# ...
# }
# value {
# int|short|float|bool|string <value>
# [ int|short|float|bool|string <value> ]
# ...
# }
# }
# <param 2 name > {<param> <value>}
# ...
# }
# ...
# }
# ...
# }
#
# TODO: add default audio pre processor configurations after debug and tuning phase
#
System is still "Read Only"
So no luck achieving this yet. We gotta wait till a Kernel comes around.
JazonX said:
System is still "Read Only"
So no luck achieving this yet. We gotta wait till a Kernel comes around.
Click to expand...
Click to collapse
Hm, what you mean? Can't we go around that with magisk? I was able to edit file systems. Doesn't V4A just need to read them?
Also, the S21+ also seems to have a RO system (couldn't even rename files inside vendor) and V4A worked just fine.
JazonX said:
System is still "Read Only"
So no luck achieving this yet. We gotta wait till a Kernel comes around.
Click to expand...
Click to collapse
Just flashed Aurora ROM, which has RW System, and I still got driver installation loop. Are you sure this is the cause?
In terms of v4a i had to modify post-fs-data to get it working although i didnt had driver installation looping
Be_Cruel. said:
In terms of v4a i had to modify post-fs-data to get it working although i didnt had driver installation looping
Click to expand...
Click to collapse
Is your device Exynos or SD? Because exynos doesn't seem to hve this issue. I tried editing post-fs-data.sh as well...
ffp. said:
Is your device Exynos or SD? Because exynos doesn't seem to hve this issue. I tried editing post-fs-data.sh as well...
Click to expand...
Click to collapse
Yea i do have exy
Any inroads to v4a working on the s908e....?
Why this device having issues when v4a works fine on other snapdragon devices.
elmor0 said:
Any inroads to v4a working on the s908e....?
Why this device having issues when v4a works fine on other snapdragon devices.
Click to expand...
Click to collapse
Any working link for a newer version ?
I have System R/W now. I can check.
I've tried with R/W (permissive kernel & TWRP) - still get v4a install driver loop.
How did you get System R/W?
Links wise, try:
https://zackptg5.com/downloads/v4afx_v2.7.2.1.zip
GitHub - programminghoch10/ViPER4AndroidRepackaged: A refined ViPER4Android installer.
A refined ViPER4Android installer. Contribute to programminghoch10/ViPER4AndroidRepackaged development by creating an account on GitHub.
github.com
ViPER4Android Updates
- Improved loading logic for convolution files - Fixed an issue when installing the module on older Magisk versions - Bug fixes - Stability improvements Check out XDA for the release notes
t.me
Please let me know how it goes.

Categories

Resources