Compare commits

..

4 commits

Author SHA1 Message Date
Pranav Vashi
82edcb6260 AttestationService: Fixes and tune up
* Increase interval from 5 minutes to 8 hours. For 10k+ active users, having
  small interval may load server with too many requests.
* When internet is not available, defer the update instead of cancelling.
* Fix SPOOF_PIXEL_PI being checked only boot. User may toggle it while using ROM.
  We should check it during scheduling instead.

Signed-off-by: Pranav Vashi <neobuddy89@gmail.com>
2025-04-17 22:04:00 +00:00
SamarV-121
b9537c6a51 PixelPropsUtils: Dynamically spoof props for GMS
neobuddy89: Adapted for PixelPropsUtils. Use local props as fallback.

Signed-off-by: Pranav Vashi <neobuddy89@gmail.com>
2025-04-17 22:04:00 +00:00
Pranav Vashi
d9682eafe0 PixelPropsUtils: Move certified props to vendor
* Ref and credits:
https://github.com/AOSPA/android_frameworks_base/blob/uvite/core/java/com/android/internal/util/PropImitationHooks.java

Change-Id: Ie09e0f29bff068968c92c9eace5e981381825157
Signed-off-by: Pranav Vashi <neobuddy89@gmail.com>
2025-04-17 22:03:58 +00:00
jhenrique09
a8011f7594 Introduce PixelPropsUtils for safety net spoof [SQUASHED]
* That will spoof build fingerprints on some g00gle apps
* Thanks to kdrag0n for the original idea at
  5a54bfd846

@neobuddy89:
* Squash subsequent changes by jhenrique09, SKULSHADY, Stallix

Co-authored-by: Danny Lin <danny@kdrag0n.dev>
Signed-off-by: jhenrique09 <jhenrique09.mcz@hotmail.com>
Signed-off-by: Pranav Vashi <neobuddy89@gmail.com>

Also squashed commit of the following:

commit 780615526b4df07c0673c344ea65b1b9bb38f6c0
Author: jhenrique09 <jhenrique09.mcz@hotmail.com>
Date:   Tue Nov 8 12:33:47 2022 +0800

    PixelPropsUtils: Get package name from context instead of app

    11-04 08:48:39.039 11637 11637 E AndroidRuntime: FATAL EXCEPTION: main
    11-04 08:48:39.039 11637 11637 E AndroidRuntime: Process: com.NextFloor.DestinyChild, PID: 11637
    11-04 08:48:39.039 11637 11637 E AndroidRuntime: java.lang.RuntimeException: Unable to get provider androidx.startup.InitializationProvider: androidx.startup.StartupException: android.content.pm.PackageManager$NameNotFoundException: ComponentInfo{/androidx.startup.InitializationProvider}
    11-04 08:48:39.039 11637 11637 E AndroidRuntime:   at android.app.ActivityThread.installProvider(ActivityThread.java:7488)

    Change-Id: Icb12f938fe0fca710f8f9d29182d0134ba3c63eb
    Signed-off-by: Pranav Vashi <neobuddy89@gmail.com>

commit df0a1a8f9ce6c97474438798cd43f21355c0f1e9
Author: EnesSastim <sastimenes@gmail.com>
Date:   Tue Oct 25 14:04:49 2022 +0000

    PixelPropsUtils: Don't spoof euicc

    Signed-off-by: Pranav Vashi <neobuddy89@gmail.com>

commit f10adfa0d2cd767dfb942ecfc6f52568fce4146f
Author: Pranav Vashi <neobuddy89@gmail.com>
Date:   Sun Oct 16 00:31:02 2022 +0530

    PixelPropsUtils: Update pixel devices list

    Signed-off-by: Pranav Vashi <neobuddy89@gmail.com>

commit f567f3c30163364d10598eb65871f65aae3b44d4
Author: Dyneteve <dyneteve@hentaios.com>
Date:   Tue Aug 23 18:57:05 2022 +0200

    PixelPropsUtils: Apply key attestation workaround to Play Store as well

    Play Store is used for the new Play Integrity API, extend the hack
    to it as well.

    Test: Device Integrity and Basic Integrity passes.

    Change-Id: Id607cdff0b902f285a6c1b769c0a4ee4202842b1
    Signed-off-by: Dyneteve <dyneteve@hentaios.com>
    Signed-off-by: Pranav Vashi <neobuddy89@gmail.com>

commit 4c557fd6ff68eed3e587d0ac2842647e75df904d
Author: Joey Huab <joey@evolution-x.org>
Date:   Thu Oct 13 13:06:00 2022 +0000

    PixelPropsUtils: Switch from raven fp to cheetah

    * Update packages
    * Remove GMS as we are setting it to angler

    Signed-off-by: Pranav Vashi <neobuddy89@gmail.com>

commit 1ab2ce29eb1a259522b3c8a3638ce60b095e1a97
Author: Alexander Winkowski <dereference23@outlook.com>
Date:   Fri Oct 14 23:25:32 2022 +0200

    PixelPropsUtils: Spoof Nexus 6P for GMS unstable process

    To fix Play Integrity, taken from https://github.com/kdrag0n/safetynet-fix/pull/207

    Signed-off-by: Pranav Vashi <neobuddy89@gmail.com>

commit 6f386d6ac22c8a43b7381177600aa0e11c472217
Author: Akash Srivastava <akashniki@gmail.com>
Date:   Sat Aug 20 19:04:32 2022 +0700

    core: Pixel experience Blacklist For Google Photos for Android 13

    * See, in Android 13 pixel_experience_2022_midyear was added, which needs to be blacklisted aswell
    * Also bring in PIXEL_2021_EXPERIENCE which was missing

    Change-Id: Id36d12afeda3cf6b39d01a0dbe7e3e9058659b8e
    Signed-off-by: Pranav Vashi <neobuddy89@gmail.com>

commit e819f8fb14924c32abce93cccc14fd9ea69b032b
Author: Joey Huab <joey@evolution-x.org>
Date:   Mon Aug 15 18:23:48 2022 +0000

    PixelPropsUtils: Update game props

    * Removed new state as multiple crash reports.

    Signed-off-by: Pranav Vashi <neobuddy89@gmail.com>

commit 845fbd03cd9c521d0daa4cad63a7aa55aacfa995
Author: Pranav Vashi <neobuddy89@gmail.com>
Date:   Sat Sep 10 21:23:33 2022 +0530

    PixelPropsUtils: Use ro.build.incremental for settings intelligence

    Signed-off-by: Pranav Vashi <neobuddy89@gmail.com>

commit 328b97baa8039e4b127585ac467846faf5f13cb9
Author: johnmart19 <johnivan19999@gmail.com>
Date:   Mon Jul 11 01:37:47 2022 +0300

    PixelPropsUtils: GameProps: Hide Apex Legends as Mi11

    Change-Id: I80b0136ef75f61154011ed7831994ffe8b5f5c96
    Signed-off-by: Pranav Vashi <neobuddy89@gmail.com>

commit 1ddc5fc26838c3ab4592646028601c194b1cefee
Author: Danny Lin <danny@kdrag0n.dev>
Date:   Mon Nov 1 20:06:48 2021 -0700

    PixelPropsUtils: Limit SafetyNet workarounds to unstable GMS process

    The unstable process is where SafetyNet attestation actually runs, so
    we only need to spoof the model in that process.

    Change-Id: Idcf663907a6c3d0408dbd45b1ac53c9eb4200df8
    Signed-off-by: Pranav Vashi <neobuddy89@gmail.com>

commit ea1e57ba3fd786f62f94d4860cbc18eb3e81a074
Author: Pranav Vashi <neobuddy89@gmail.com>
Date:   Sun May 29 19:34:09 2022 +0530

    PixelPropsUtils: Exclude recorder from pixel props

    * Just like YouTube apps, Recorder shows device is Pixel 5.
      There is no special pixel feature associated with this app, exclude it.

    Signed-off-by: Pranav Vashi <neobuddy89@gmail.com>

commit b52ac41246b1bc15b0316c58ae7516f3b272643d
Author: Anay Wadhera <awadhera@berkeley.edu>
Date:   Fri Dec 10 13:11:49 2021 -0800

    PixelPropsUtils: Remove spoofing for currently supported Pixel devices

    @neobuddy89: Selectively enabled for GPhotos spoof.

    Change-Id: I3a426f8671f841c16e5af7c0a2a204d19c502464
    Signed-off-by: Pranav Vashi <neobuddy89@gmail.com>

commit ce68c443c392c9be6fd0591958db960a1f10f9e3
Author: Pranav Vashi <neobuddy89@gmail.com>
Date:   Sat Mar 26 12:32:23 2022 +0530

    PixelPropsUtils: Add game props for mobile legends

    Signed-off-by: Pranav Vashi <neobuddy89@gmail.com>

commit c56868a33f61bbed50aff989271e5b204333a3e1
Author: Omkar Chandorkar <gotenksIN@aosip.dev>
Date:   Sat Mar 5 02:35:21 2022 +0900

    PixelPropsUtils: Only spoof GMS to Raven

    * please shut the fuck up EdgeTpuDeviceFactory

    Change-Id: I2ef71a12e613bee7a01e27ae36f9b07a3b78e766
    Signed-off-by: Omkar Chandorkar <gotenksIN@aosip.dev>
    Signed-off-by: Pranav Vashi <neobuddy89@gmail.com>

commit 75ae3f4d46fa39ac9ea44ada3f3e79dcc660d684
Author: Pranav Vashi <neobuddy89@gmail.com>
Date:   Sun Feb 27 15:23:50 2022 +0530

    PixelPropsUtils: Whitelist YouTube apps

    * Otherwise casting shows wrong device connected.

    Signed-off-by: Pranav Vashi <neobuddy89@gmail.com>

commit 351c31da421ce13587e6b621b47c483a821f3023
Author: Joey Huab <joey@evolution-x.org>
Date:   Tue Feb 15 17:32:11 2022 +0900

    PixelPropsUtils: Refactor Pixel 2021 features availability

    * Apparently, Magic Eraser currently requires a
      specific Photos version for it to show up and
      actually work.
      APK: https://apkmirror.com/apk/google-inc/photos/photos-5-65-0-405472367-release/google-photos-5-65-0-405472367-10-android-apk-download

    * Basically, Magic Eraser feature will crash if
      Photos is spoofed as Pixel XL. We want to
      make Magic Eraser work by default as long as
      the Unlimited Photos spoof is turned off.

    * Set Pixel 5 as spoof for more Google apps that
      uses TPU when spoofed as Pixel 6.

    * Default Pixel 5 spoof for Photos and only switch
      to Pixel XL when spoof is toggled.

    * Pixel Buds has been reported to crash on Pixel 6 spoof
      so move it to Pixel 5.

    * Keep Google Translate to Pixel 5 as it's not really as
      used as the others.

    * We will try to bypass 2021 features and Raven
      props for non-Pixel 2021 devices as apps usage
      requires TPU.

    @neobuddy89:
    * Updated description to align with changes we made.
    * oriole and raven devices can add PIXEL_2021_EXPERIENCE xml
    * TODO: Skip PixelPropUtils for select pixel devices?

    Signed-off-by: Pranav Vashi <neobuddy89@gmail.com>

commit 8d65b4cd3ae65bb711ea7da5fafa3ecc92268769
Author: Pranav Vashi <neobuddy89@gmail.com>
Date:   Sat Feb 12 22:27:33 2022 +0530

    PixelPropsUtils: User toggle for GamesProp [1/2]

    * Disabled by default.

    Signed-off-by: Pranav Vashi <neobuddy89@gmail.com>

commit c28564cec076e0ebc9ca84e5f832837668d12cc5
Author: spezi77 <spezi7713@gmx.net>
Date:   Mon Jan 31 01:02:38 2022 +0100

    PixelPropsUtils: User toggle for unlimited photos storage [1/2]

    @neobuddy89: Cleaned up.

    Squashed:
        From: Kuba Wojciechowski <nullbytepl@gmail.com>
        Date: Fri, 5 Nov 2021 01:52:51 +0300
        Subject: [PATCH] core: Blacklist P21 experience system feature from Google
         Photos

        We want to include the P21 experience flag to enable new features,
        however it seems like Google Photos uses it to decide whether to use the
        TPU tflite delegate. There doesn't seem to be any fallback so we need to
        make sure the feature is not exposed to the app so that a normal
        NNAPI/GPU delegate can be used instead.

        From: naveenjohnsonv <14140949+naveenjohnsonv@users.noreply.github.com>
        Date: Mon, 13 Dec 2021 07:16:55 +0000
        Subject: [PATCH] core: Blacklist P21 midyear, P20, P20 midyear experience
         system feature from Google Photos

        naveenjohnsonv: also blacklist PIXEL_2021_MIDYEAR_EXPERIENCE, PIXEL_2020_EXPERIENCE and PIXEL_2020_MIDYEAR_EXPERIENCE from Google Photos
        Along with crosshatch spoof for Google Photos using PixelPropUtils, this should enable Unlimited Original Quality Backup without needing to remove any XMLs

        From: kondors1995 <normandija1945@gmail.com>
        Date: Mon, 20 Dec 2021 16:53:46 +0000
        Subject: [PATCH] Core: Extend Pixel experience Blacklist For Google Photos

        Turns out having these brakes Original quality backups.
        Since these indicate that the device is pixel 4 with in the turn brakes device spoofing as OG pixel

    Signed-off-by: Pranav Vashi <neobuddy89@gmail.com>

commit 50eeca3957d614362655a9846ba29c7d47319953
Author: Joey Huab <joey@evolution-x.org>
Date:   Thu Jan 27 13:33:48 2022 +0900

    PixelPropsUtils: Whitelist ARCore

    * ARCore crashes due to being spoofed as hardware and software mismatch is detected.
    * Crash occurs while being used in Google app search feature.

    Signed-off-by: Pranav Vashi <neobuddy89@gmail.com>

commit e3758d43036f5f38492d079bcaf2f249b9f88574
Author: Pranav Vashi <neobuddy89@gmail.com>
Date:   Tue Jan 11 09:49:00 2022 +0530

    PixelPropsUtils: Bail out early when required

    Signed-off-by: Pranav Vashi <neobuddy89@gmail.com>

commit fdfe58f4c4ef89d5e5840daa137c31c75e732c7b
Author: Pranav Vashi <neobuddy89@gmail.com>
Date:   Tue Jan 11 09:43:53 2022 +0530

    PixelPropsUtils: Extend list of packages to keep

    * It's better to not touch props for these packages at all,
      instead running loop over it.
    * Ref: dc2940c18c

    Signed-off-by: Pranav Vashi <neobuddy89@gmail.com>

commit e2ebc7e0d3e74bff76f1cdc56e958c1f07fd4c0b
Author: rdkng1 <richardraya39@gmail.com>
Date:   Sat Dec 11 05:17:22 2021 +0000

    PixelPropsUtils: Add GamesProps

      Based on PixelPropsUtils, GamesProps will spoof the device needed to unlock the FPS of the following games:
      * Free Fire - Spoof Asus ROG Phone 1 will unlock 90 FPS
      * COD Mobile - Spoof Xperia 5 || will unlock 120 FPS (only on multiplayer mode)
      * PUBG Mobile - Spoof OnePlus 8 Pro will unlock 90 FPS
      * Wild Rift - Spoof OnePlus 8 Pro will unlock 120 FPS
      * Cyber Hunter - Spoof OnePlus 8 Pro will unlock 90 FPS
      * Fortnite - Spoof OnePlus 8 Pro will unlock 90 FPS

    @neobuddy89: Adapt GamesProps to existing PixelProps and update games list.

    Signed-off-by: Pranav Vashi <neobuddy89@gmail.com>

commit e8353f537654f22b8236ab34d700c092049655cd
Author: Pranav Vashi <neobuddy89@gmail.com>
Date:   Mon Jan 10 22:55:33 2022 +0530

    PixelPropsUtils: Consolidate google app checks

    Signed-off-by: Pranav Vashi <neobuddy89@gmail.com>

commit 5079c980a5dc4ed220c4e92713d67785809f1212
Author: Pranav Vashi <neobuddy89@gmail.com>
Date:   Sat Jan 8 18:35:43 2022 +0530

    PixelPropsUtils: Do not change props for play store

    * Else Play Protect certification fails.

    Test: Open Play Store > Settings > About
    Signed-off-by: Pranav Vashi <neobuddy89@gmail.com>

commit 8bd8e4d4741226075823e485b60dbe24a4fb5a73
Author: Danny Lin <danny@kdrag0n.dev>
Date:   Mon Oct 11 20:00:44 2021 -0700

    keystore: Block key attestation for SafetyNet

    SafetyNet (part of Google Play Services) opportunistically uses
    hardware-backed key attestation via KeyStore as a strong integrity
    check. This causes SafetyNet to fail on custom ROMs because the verified
    boot key and bootloader unlock state can be detected from attestation
    certificates.

    As a workaround, we can take advantage of the fact that SafetyNet's
    usage of key attestation is opportunistic (i.e. falls back to basic
    integrity checks if it fails) and prevent it from getting the
    attestation certificate chain from KeyStore. This is done by checking
    the stack for DroidGuard, which is the codename for SafetyNet, and
    pretending that the device doesn't support key attestation.

    Key attestation has only been blocked for SafetyNet specifically, as
    Google Play Services and other apps have many valid reasons to use it.
    For example, it appears to be involved in Google's mobile security key
    ferature.

    Change-Id: I5146439d47f42dc6231cb45c4dab9f61540056f6
    Signed-off-by: Pranav Vashi <neobuddy89@gmail.com>

Change-Id: I2481b6789f33f4f2ec49637f545023bf7d34b7ca
Signed-off-by: Pranav Vashi <neobuddy89@gmail.com>
2025-04-17 15:26:27 +00:00
8 changed files with 803 additions and 0 deletions

View file

@ -834,8 +834,104 @@ public class ApplicationPackageManager extends PackageManager {
}
};
private static final String[] pTensorCodenames = {
"comet",
"komodo",
"caiman",
"tokay",
"akita",
"husky",
"shiba",
"felix",
"tangorpro",
"lynx",
"cheetah",
"panther",
"bluejay",
"oriole",
"raven"
};
private static final String[] featuresPixel = {
"com.google.android.apps.photos.PIXEL_2019_PRELOAD",
"com.google.android.apps.photos.PIXEL_2019_MIDYEAR_PRELOAD",
"com.google.android.apps.photos.PIXEL_2018_PRELOAD",
"com.google.android.apps.photos.PIXEL_2017_PRELOAD",
"com.google.android.feature.PIXEL_2021_MIDYEAR_EXPERIENCE",
"com.google.android.feature.PIXEL_2020_EXPERIENCE",
"com.google.android.feature.PIXEL_2020_MIDYEAR_EXPERIENCE",
"com.google.android.feature.PIXEL_2019_EXPERIENCE",
"com.google.android.feature.PIXEL_2019_MIDYEAR_EXPERIENCE",
"com.google.android.feature.PIXEL_2018_EXPERIENCE",
"com.google.android.feature.PIXEL_2017_EXPERIENCE",
"com.google.android.feature.PIXEL_EXPERIENCE",
"com.google.android.feature.GOOGLE_BUILD",
"com.google.android.feature.GOOGLE_EXPERIENCE"
};
private static final String[] featuresPixelOthers = {
"com.google.android.feature.ASI",
"com.google.android.feature.ANDROID_ONE_EXPERIENCE",
"com.google.android.feature.GOOGLE_FI_BUNDLED",
"com.google.android.feature.LILY_EXPERIENCE",
"com.google.android.feature.TURBO_PRELOAD",
"com.google.android.feature.WELLBEING",
"com.google.lens.feature.IMAGE_INTEGRATION",
"com.google.lens.feature.CAMERA_INTEGRATION",
"com.google.photos.trust_debug_certs",
"com.google.android.feature.AER_OPTIMIZED",
"com.google.android.feature.NEXT_GENERATION_ASSISTANT",
"android.software.game_service",
"com.google.android.feature.EXCHANGE_6_2",
"com.google.android.apps.dialer.call_recording_audio",
"com.google.android.apps.dialer.SUPPORTED"
};
private static final String[] featuresTensor = {
"com.google.android.feature.PIXEL_2025_EXPERIENCE",
"com.google.android.feature.PIXEL_2025_MIDYEAR_EXPERIENCE",
"com.google.android.feature.PIXEL_2024_EXPERIENCE",
"com.google.android.feature.PIXEL_2024_MIDYEAR_EXPERIENCE",
"com.google.android.feature.PIXEL_2023_EXPERIENCE",
"com.google.android.feature.PIXEL_2023_MIDYEAR_EXPERIENCE",
"com.google.android.feature.PIXEL_2022_EXPERIENCE",
"com.google.android.feature.PIXEL_2022_MIDYEAR_EXPERIENCE",
"com.google.android.feature.PIXEL_2021_EXPERIENCE"
};
private static final String[] featuresNexus = {
"com.google.android.apps.photos.NEXUS_PRELOAD",
"com.google.android.apps.photos.nexus_preload",
"com.google.android.feature.PIXEL_EXPERIENCE",
"com.google.android.feature.GOOGLE_BUILD",
"com.google.android.feature.GOOGLE_EXPERIENCE"
};
@Override
public boolean hasSystemFeature(String name, int version) {
String packageName = ActivityThread.currentPackageName();
if (packageName != null
&& (packageName.equals("com.google.android.googlequicksearchbox")
|| packageName.equals("com.google.android.apps.nexuslauncher"))) {
if (Arrays.asList(featuresPixel).contains(name)) return true;
if (Arrays.asList(featuresPixelOthers).contains(name)) return true;
if (Arrays.asList(featuresTensor).contains(name)) return true;
if (Arrays.asList(featuresNexus).contains(name)) return true;
}
if (packageName != null
&& packageName.equals("com.google.android.apps.photos")
&& SystemProperties.getBoolean("persist.sys.pixelprops.gphotos", true)) {
if (Arrays.asList(featuresPixel).contains(name)) return false;
if (Arrays.asList(featuresPixelOthers).contains(name)) return true;
if (Arrays.asList(featuresTensor).contains(name)) return false;
if (Arrays.asList(featuresNexus).contains(name)) return true;
}
if (name != null && Arrays.asList(featuresTensor).contains(name)
&& !Arrays.asList(pTensorCodenames).contains(SystemProperties.get("ro.product.device"))) {
return false;
}
if (Arrays.asList(featuresPixel).contains(name)) return true;
if (Arrays.asList(featuresPixelOthers).contains(name)) return true;
return mHasSystemFeatureCache.query(new HasSystemFeatureQuery(name, version));
}

View file

@ -75,6 +75,8 @@ import java.util.Objects;
import java.util.StringJoiner;
import java.util.concurrent.TimeoutException;
import com.android.internal.util.crdroid.PixelPropsUtils;
/**
* Base class for implementing application instrumentation code. When running
* with instrumentation turned on, this class will be instantiated for you
@ -1356,6 +1358,7 @@ public class Instrumentation {
Application app = getFactory(context.getPackageName())
.instantiateApplication(cl, className);
app.attach(context);
PixelPropsUtils.setProps(context);
return app;
}
@ -1373,6 +1376,7 @@ public class Instrumentation {
ClassNotFoundException {
Application app = (Application)clazz.newInstance();
app.attach(context);
PixelPropsUtils.setProps(context);
return app;
}

View file

@ -0,0 +1,470 @@
/*
* Copyright (C) 2020 The Pixel Experience Project
* 2021-2025 crDroid Android Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.internal.util.crdroid;
import android.app.Application;
import android.content.Context;
import android.content.res.Configuration;
import android.os.Build;
import android.os.Environment;
import android.os.SystemProperties;
import android.text.TextUtils;
import android.util.Log;
import com.android.internal.R;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
/**
* @hide
*/
public final class PixelPropsUtils {
private static final String TAG = PixelPropsUtils.class.getSimpleName();
private static final String DEVICE = "ro.product.device";
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
private static final String DATA_FILE = "gms_certified_props.json";
private static final String SPOOF_PIXEL_PI = "persist.sys.pixelprops.pi";
private static final String SPOOF_PIXEL_GAMES = "persist.sys.pixelprops.games";
private static final String SPOOF_PIXEL_GPHOTOS = "persist.sys.pixelprops.gphotos";
private static final String SPOOF_PIXEL_NETFLIX = "persist.sys.pixelprops.netflix";
private static final Map<String, Object> propsToChangeGeneric;
private static final Map<String, Object> propsToChangePixel9ProXL;
private static final Map<String, Object> propsToChangePixelTablet;
private static final Map<String, Object> propsToChangePixelXL;
private static final Map<String, Object> propsToChangeROG6;
private static final Map<String, Object> propsToChangeLenovoY700;
private static final Map<String, Object> propsToChangeOP8P;
private static final Map<String, Object> propsToChangeOP9P;
private static final Map<String, Object> propsToChangeMI11TP;
private static final Map<String, Object> propsToChangeMI13P;
private static final Map<String, Object> propsToChangeF5;
private static final Map<String, Object> propsToChangeBS4;
private static final Map<String, Object> propsToChangeS24U;
// Packages to Spoof as the most recent Pixel device
private static final String[] packagesToChangeRecentPixel = {
"com.android.vending",
"com.google.android.aicore",
"com.google.android.apps.aiwallpapers",
"com.google.android.apps.bard",
"com.google.android.apps.customization.pixel",
"com.google.android.apps.emojiwallpaper",
"com.google.android.apps.nexuslauncher",
"com.google.android.apps.photos",
"com.google.android.apps.pixel.agent",
"com.google.android.apps.pixel.creativeassistant",
"com.google.android.apps.pixel.support",
"com.google.android.apps.privacy.wildlife",
"com.google.android.apps.wallpaper",
"com.google.android.apps.wallpaper.pixel",
"com.google.android.apps.weather",
"com.google.android.gms",
"com.google.android.googlequicksearchbox",
"com.google.android.settings.intelligence",
"com.google.android.wallpaper.effects",
"com.google.pixel.livewallpaper",
"com.netflix.mediaclient",
"com.nhs.online.nhsonline"
};
// Packages to Spoof as ROG Phone 6
private static final String[] packagesToChangeROG6 = {
"com.ea.gp.fifamobile",
"com.gameloft.android.ANMP.GloftA9HM",
"com.madfingergames.legends",
"com.pearlabyss.blackdesertm",
"com.pearlabyss.blackdesertm.gl"
};
// Packages to Spoof as Lenovo Y700
private static final String[] packagesToChangeLenovoY700 = {
"com.activision.callofduty.shooter",
"com.garena.game.codm",
"com.tencent.tmgp.kr.codm",
"com.vng.codmvn"
};
// Packages to Spoof as OnePlus 8 Pro
private static final String[] packagesToChangeOP8P = {
"com.netease.lztgglobal",
"com.riotgames.league.wildrift",
"com.riotgames.league.wildrifttw",
"com.riotgames.league.wildriftvn",
"com.riotgames.league.teamfighttactics",
"com.riotgames.league.teamfighttacticstw",
"com.riotgames.league.teamfighttacticsvn"
};
// Packages to Spoof as OnePlus 9 Pro
private static final String[] packagesToChangeOP9P = {
"com.epicgames.fortnite",
"com.epicgames.portal",
"com.tencent.lolm"
};
// Packages to Spoof as Mi 11T Pro
private static final String[] packagesToChangeMI11TP = {
"com.ea.gp.apexlegendsmobilefps",
"com.levelinfinite.hotta.gp",
"com.supercell.clashofclans",
"com.vng.mlbbvn"
};
// Packages to Spoof as Xiaomi 13 Pro
private static final String[] packagesToChangeMI13P = {
"com.levelinfinite.sgameGlobal",
"com.tencent.tmgp.sgame"
};
// Packages to Spoof as POCO F5
private static final String[] packagesToChangeF5 = {
"com.dts.freefiremax",
"com.dts.freefireth",
"com.mobile.legends"
};
// Packages to Spoof as Black Shark 4
private static final String[] packagesToChangeBS4 = {
"com.proximabeta.mf.uamo"
};
// Packages to Spoof as Samsung S24 Ultra
private static final String[] packagesToChangeS24U = {
"com.pubg.imobile",
"com.pubg.krmobile",
"com.rekoo.pubgm",
"com.tencent.ig",
"com.tencent.tmgp.pubgmhd",
"com.vng.pubgmobile"
};
private static volatile boolean sIsFinsky = false;
private static volatile List<String> sCertifiedProps = new ArrayList<>();
static {
propsToChangeGeneric = new HashMap<>();
propsToChangeGeneric.put("TYPE", "user");
propsToChangeGeneric.put("TAGS", "release-keys");
propsToChangePixel9ProXL = new HashMap<>();
propsToChangePixel9ProXL.put("BRAND", "google");
propsToChangePixel9ProXL.put("MANUFACTURER", "Google");
propsToChangePixel9ProXL.put("DEVICE", "komodo");
propsToChangePixel9ProXL.put("PRODUCT", "komodo");
propsToChangePixel9ProXL.put("HARDWARE", "komodo");
propsToChangePixel9ProXL.put("MODEL", "Pixel 9 Pro XL");
propsToChangePixel9ProXL.put("ID", "BP1A.250405.007");
propsToChangePixel9ProXL.put("FINGERPRINT", "google/komodo/komodo:15/BP1A.250405.007/13240079:user/release-keys");
propsToChangePixelTablet = new HashMap<>();
propsToChangePixelTablet.put("BRAND", "google");
propsToChangePixelTablet.put("MANUFACTURER", "Google");
propsToChangePixelTablet.put("DEVICE", "tangorpro");
propsToChangePixelTablet.put("PRODUCT", "tangorpro");
propsToChangePixelTablet.put("HARDWARE", "tangorpro");
propsToChangePixelTablet.put("MODEL", "Pixel Tablet");
propsToChangePixelTablet.put("ID", "BP1A.250405.007");
propsToChangePixelTablet.put("FINGERPRINT", "google/tangorpro/tangorpro:15/BP1A.250405.007/13240079:user/release-keys");
propsToChangePixelXL = new HashMap<>();
propsToChangePixelXL.put("BRAND", "google");
propsToChangePixelXL.put("MANUFACTURER", "Google");
propsToChangePixelXL.put("DEVICE", "marlin");
propsToChangePixelXL.put("PRODUCT", "marlin");
propsToChangePixelXL.put("HARDWARE", "marlin");
propsToChangePixelXL.put("MODEL", "Pixel XL");
propsToChangePixelXL.put("ID", "QP1A.191005.007.A3");
propsToChangePixelXL.put("FINGERPRINT", "google/marlin/marlin:10/QP1A.191005.007.A3/5972272:user/release-keys");
propsToChangeROG6 = new HashMap<>();
propsToChangeROG6.put("BRAND", "asus");
propsToChangeROG6.put("MANUFACTURER", "asus");
propsToChangeROG6.put("DEVICE", "AI2201");
propsToChangeROG6.put("MODEL", "ASUS_AI2201");
propsToChangeLenovoY700 = new HashMap<>();
propsToChangeLenovoY700.put("MODEL", "Lenovo TB-9707F");
propsToChangeLenovoY700.put("MANUFACTURER", "lenovo");
propsToChangeOP8P = new HashMap<>();
propsToChangeOP8P.put("MODEL", "IN2020");
propsToChangeOP8P.put("MANUFACTURER", "OnePlus");
propsToChangeOP9P = new HashMap<>();
propsToChangeOP9P.put("MODEL", "LE2123");
propsToChangeOP9P.put("MANUFACTURER", "OnePlus");
propsToChangeMI11TP = new HashMap<>();
propsToChangeMI11TP.put("MODEL", "2107113SI");
propsToChangeMI11TP.put("MANUFACTURER", "Xiaomi");
propsToChangeMI13P = new HashMap<>();
propsToChangeMI13P.put("BRAND", "Xiaomi");
propsToChangeMI13P.put("MANUFACTURER", "Xiaomi");
propsToChangeMI13P.put("MODEL", "2210132C");
propsToChangeF5 = new HashMap<>();
propsToChangeF5.put("MODEL", "23049PCD8G");
propsToChangeF5.put("MANUFACTURER", "Xiaomi");
propsToChangeBS4 = new HashMap<>();
propsToChangeBS4.put("MODEL", "2SM-X706B");
propsToChangeBS4.put("MANUFACTURER", "blackshark");
propsToChangeS24U = new HashMap<>();
propsToChangeS24U.put("BRAND", "SAMSUNG");
propsToChangeS24U.put("DEVICE", "S24 ULTRA");
propsToChangeS24U.put("MANUFACTURER", "SM-S928B");
propsToChangeS24U.put("MODEL", "SM-S928B");
}
public static void setProps(Context context) {
final String packageName = context.getPackageName();
if (packageName == null || packageName.isEmpty()) {
return;
}
propsToChangeGeneric.forEach((k, v) -> setPropValue(k, v));
if (Arrays.asList(packagesToChangeRecentPixel).contains(packageName)) {
Map<String, Object> propsToChange = new HashMap<>();
if (packageName.equals("com.google.android.apps.photos")) {
if (SystemProperties.getBoolean(SPOOF_PIXEL_GPHOTOS, true)) {
propsToChange.putAll(propsToChangePixelXL);
}
} else if (packageName.equals("com.netflix.mediaclient") &&
!SystemProperties.getBoolean(SPOOF_PIXEL_NETFLIX, false)) {
if (DEBUG) Log.d(TAG, "Netflix spoofing disabled by system prop");
return;
} else if (packageName.equals("com.android.vending")) {
sIsFinsky = true;
return;
} else if (packageName.equals("com.google.android.gms")) {
final String processName = Application.getProcessName().toLowerCase();
if (processName.contains("unstable")) {
spoofBuildGms(context);
return;
}
return;
} else if (packageName.equals("com.google.android.settings.intelligence")) {
setPropValue("FINGERPRINT", Build.VERSION.INCREMENTAL);
return;
} else {
if (isDeviceTablet(context.getApplicationContext())) {
propsToChange.putAll(propsToChangePixelTablet);
} else {
propsToChange.putAll(propsToChangePixel9ProXL);
}
}
if (DEBUG) Log.d(TAG, "Defining props for: " + packageName);
for (Map.Entry<String, Object> prop : propsToChange.entrySet()) {
String key = prop.getKey();
Object value = prop.getValue();
if (DEBUG) Log.d(TAG, "Defining " + key + " prop for: " + packageName);
setPropValue(key, value);
}
} else {
if (!SystemProperties.getBoolean(SPOOF_PIXEL_GAMES, false))
return;
if (Arrays.asList(packagesToChangeROG6).contains(packageName)) {
if (DEBUG) Log.d(TAG, "Defining props for: " + packageName);
for (Map.Entry<String, Object> prop : propsToChangeROG6.entrySet()) {
String key = prop.getKey();
Object value = prop.getValue();
setPropValue(key, value);
}
} else if (Arrays.asList(packagesToChangeLenovoY700).contains(packageName)) {
if (DEBUG) Log.d(TAG, "Defining props for: " + packageName);
for (Map.Entry<String, Object> prop : propsToChangeLenovoY700.entrySet()) {
String key = prop.getKey();
Object value = prop.getValue();
setPropValue(key, value);
}
} else if (Arrays.asList(packagesToChangeOP8P).contains(packageName)) {
if (DEBUG) Log.d(TAG, "Defining props for: " + packageName);
for (Map.Entry<String, Object> prop : propsToChangeOP8P.entrySet()) {
String key = prop.getKey();
Object value = prop.getValue();
setPropValue(key, value);
}
} else if (Arrays.asList(packagesToChangeOP9P).contains(packageName)) {
if (DEBUG) Log.d(TAG, "Defining props for: " + packageName);
for (Map.Entry<String, Object> prop : propsToChangeOP9P.entrySet()) {
String key = prop.getKey();
Object value = prop.getValue();
setPropValue(key, value);
}
} else if (Arrays.asList(packagesToChangeMI11TP).contains(packageName)) {
if (DEBUG) Log.d(TAG, "Defining props for: " + packageName);
for (Map.Entry<String, Object> prop : propsToChangeMI11TP.entrySet()) {
String key = prop.getKey();
Object value = prop.getValue();
setPropValue(key, value);
}
} else if (Arrays.asList(packagesToChangeMI13P).contains(packageName)) {
if (DEBUG) Log.d(TAG, "Defining props for: " + packageName);
for (Map.Entry<String, Object> prop : propsToChangeMI13P.entrySet()) {
String key = prop.getKey();
Object value = prop.getValue();
setPropValue(key, value);
}
} else if (Arrays.asList(packagesToChangeF5).contains(packageName)) {
if (DEBUG) Log.d(TAG, "Defining props for: " + packageName);
for (Map.Entry<String, Object> prop : propsToChangeF5.entrySet()) {
String key = prop.getKey();
Object value = prop.getValue();
setPropValue(key, value);
}
} else if (Arrays.asList(packagesToChangeBS4).contains(packageName)) {
if (DEBUG) Log.d(TAG, "Defining props for: " + packageName);
for (Map.Entry<String, Object> prop : propsToChangeBS4.entrySet()) {
String key = prop.getKey();
Object value = prop.getValue();
setPropValue(key, value);
}
} else if (Arrays.asList(packagesToChangeS24U).contains(packageName)) {
if (DEBUG) Log.d(TAG, "Defining props for: " + packageName);
for (Map.Entry<String, Object> prop : propsToChangeS24U.entrySet()) {
String key = prop.getKey();
Object value = prop.getValue();
setPropValue(key, value);
}
}
}
}
private static boolean isDeviceTablet(Context context) {
if (context == null) {
return false;
}
Configuration config = context.getResources().getConfiguration();
boolean isTablet = (config.smallestScreenWidthDp >= 600);
return isTablet;
}
private static void setPropValue(String key, Object value) {
setPropValue(key, value.toString());
}
private static void setPropValue(String key, String value) {
try {
if (DEBUG) Log.d(TAG, "Defining prop " + key + " to " + value);
Class<?> clazz = Build.class;
if (key.startsWith("VERSION.")) {
clazz = Build.VERSION.class;
key = key.substring(8);
}
Field field = clazz.getDeclaredField(key);
field.setAccessible(true);
// Determine the field type and parse the value accordingly.
if (field.getType().equals(Integer.TYPE)) {
field.set(null, Integer.parseInt(value));
} else if (field.getType().equals(Long.TYPE)) {
field.set(null, Long.parseLong(value));
} else {
field.set(null, value);
}
field.setAccessible(false);
} catch (Exception e) {
Log.e(TAG, "Failed to set prop " + key, e);
}
}
private static void spoofBuildGms(Context context) {
if (!SystemProperties.getBoolean(SPOOF_PIXEL_PI, true))
return;
File dataFile = new File(Environment.getDataSystemDirectory(), DATA_FILE);
String savedProps = readFromFile(dataFile);
if (TextUtils.isEmpty(savedProps)) {
Log.d(TAG, "Parsing props locally - data file unavailable");
sCertifiedProps = Arrays.asList(context.getResources().getStringArray(R.array.config_certifiedBuildProperties));
} else {
Log.d(TAG, "Parsing props fetched by attestation service");
try {
JSONObject parsedProps = new JSONObject(savedProps);
Iterator<String> keys = parsedProps.keys();
while (keys.hasNext()) {
String key = keys.next();
String value = parsedProps.getString(key);
sCertifiedProps.add(key + ":" + value);
}
} catch (JSONException e) {
Log.e(TAG, "Error parsing JSON data", e);
Log.d(TAG, "Parsing props locally as fallback");
sCertifiedProps = Arrays.asList(context.getResources().getStringArray(R.array.config_certifiedBuildProperties));
}
}
// Alter build parameters to avoid hardware attestation enforcement
for (String entry : sCertifiedProps) {
// Each entry must be of the format FIELD:value
final String[] fieldAndProp = entry.split(":", 2);
if (fieldAndProp.length != 2) {
Log.e(TAG, "Invalid entry in certified props: " + entry);
continue;
}
setPropValue(fieldAndProp[0], fieldAndProp[1]);
}
}
private static String readFromFile(File file) {
StringBuilder content = new StringBuilder();
if (file.exists()) {
try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
String line;
while ((line = reader.readLine()) != null) {
content.append(line);
}
} catch (IOException e) {
Log.e(TAG, "Error reading from file", e);
}
}
return content.toString();
}
private static boolean isCallerSafetyNet() {
return Arrays.stream(Thread.currentThread().getStackTrace())
.anyMatch(elem -> elem.getClassName().toLowerCase()
.contains("droidguard"));
}
public static void onEngineGetCertificateChain() {
if (!SystemProperties.getBoolean(SPOOF_PIXEL_PI, true))
return;
// Check stack for SafetyNet or Play Integrity
if (isCallerSafetyNet() || sIsFinsky) {
Log.i(TAG, "Blocked key attestation");
throw new UnsupportedOperationException();
}
}
}

View file

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
SPDX-FileCopyrightText: 2016-2025 crDroid Android Project
SPDX-License-Identifier: Apache-2.0
-->
<resources>
<!-- Build properties from a GMS certified device against current platform SPL level -->
<string-array name="config_certifiedBuildProperties" translatable="false">
<!--
Each entry must be of the format
FIELD:value
with the field belonging to android.os.Build or android.os.Build.VERSION class.
Example:
<item>BRAND:foo</item>
<item>DEVICE:bar</item>
<item>FINGERPRINT:foo/bar/bar:1.0/lorem/ipsum:dolor/sit-amet</item>
<item>VERSION.RELEASE:1.0</item>
-->
</string-array>
</resources>

View file

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
SPDX-FileCopyrightText: 2016-2025 crDroid Android Project
SPDX-License-Identifier: Apache-2.0
-->
<resources>
<!-- Build properties from a GMS certified device against current platform SPL level -->
<java-symbol type="array" name="config_certifiedBuildProperties" />
</resources>

View file

@ -90,6 +90,8 @@ import java.util.NoSuchElementException;
import javax.crypto.SecretKey;
import com.android.internal.util.crdroid.PixelPropsUtils;
/**
* A java.security.KeyStore interface for the Android KeyStore. An instance of
* it can be created via the {@link java.security.KeyStore#getInstance(String)
@ -178,6 +180,8 @@ public class AndroidKeyStoreSpi extends KeyStoreSpi {
@Override
public Certificate[] engineGetCertificateChain(String alias) {
PixelPropsUtils.onEngineGetCertificateChain();
KeyEntryResponse response = getKeyMetadata(alias);
if (response == null || response.metadata.certificate == null) {

View file

@ -0,0 +1,192 @@
/*
* Copyright (C) 2024 The LeafOS Project
* Copyright (C) 2024 crDroid Android Project
*
* SPDX-License-Identifier: Apache-2.0
*
*/
package com.android.server.crdroid;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.Network;
import android.net.NetworkCapabilities;
import android.os.Environment;
import android.os.SystemProperties;
import android.util.Log;
import com.android.server.SystemService;
import com.android.internal.util.crdroid.Utils;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URI;
import java.net.URL;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public final class AttestationService extends SystemService {
private static final String TAG = AttestationService.class.getSimpleName();
private static final String API = "https://raw.githubusercontent.com/crdroidandroid/android_vendor_certification/refs/heads/15.0/gms_certified_props.json";
private static final String SPOOF_PIXEL_PI = "persist.sys.pixelprops.pi";
private static final String DATA_FILE = "gms_certified_props.json";
private static final long INITIAL_DELAY = 0; // Start immediately on boot
private static final long INTERVAL = 8; // Interval in hours
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
private final Context mContext;
private final File mDataFile;
private final ScheduledExecutorService mScheduler;
private final ConnectivityManager mConnectivityManager;
private final FetchGmsCertifiedProps mFetchRunnable;
private boolean mPendingUpdate;
public AttestationService(Context context) {
super(context);
mContext = context;
mDataFile = new File(Environment.getDataSystemDirectory(), DATA_FILE);
mFetchRunnable = new FetchGmsCertifiedProps();
mScheduler = Executors.newSingleThreadScheduledExecutor();
mConnectivityManager =
(ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
registerNetworkCallback();
}
@Override
public void onStart() {}
@Override
public void onBootPhase(int phase) {
if (Utils.isPackageInstalled(mContext, "com.google.android.gms")
&& phase == PHASE_BOOT_COMPLETED) {
Log.i(TAG, "Scheduling the service");
mScheduler.scheduleAtFixedRate(
mFetchRunnable, INITIAL_DELAY, INTERVAL, TimeUnit.HOURS);
}
}
private String readFromFile(File file) {
StringBuilder content = new StringBuilder();
if (file.exists()) {
try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
String line;
while ((line = reader.readLine()) != null) {
content.append(line);
}
} catch (IOException e) {
Log.e(TAG, "Error reading from file", e);
}
}
return content.toString();
}
private void writeToFile(File file, String data) {
try (FileWriter writer = new FileWriter(file)) {
writer.write(data);
// Set -rw-r--r-- (644) permission to make it readable by others.
file.setReadable(true, false);
} catch (IOException e) {
Log.e(TAG, "Error writing to file", e);
}
}
private String fetchProps() {
try {
URL url = new URI(API).toURL();
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
try {
urlConnection.setConnectTimeout(10000);
urlConnection.setReadTimeout(10000);
try (BufferedReader reader =
new BufferedReader(new InputStreamReader(urlConnection.getInputStream()))) {
StringBuilder response = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
response.append(line);
}
return response.toString();
}
} finally {
urlConnection.disconnect();
}
} catch (Exception e) {
Log.e(TAG, "Error making an API request", e);
return null;
}
}
private void dlog(String message) {
if (DEBUG) Log.d(TAG, message);
}
private boolean isInternetConnected() {
Network network = mConnectivityManager.getActiveNetwork();
if (network != null) {
NetworkCapabilities capabilities = mConnectivityManager.getNetworkCapabilities(network);
return capabilities != null && capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
}
return false;
}
private void registerNetworkCallback() {
mConnectivityManager.registerDefaultNetworkCallback(new ConnectivityManager.NetworkCallback() {
@Override
public void onAvailable(Network network) {
Log.i(TAG, "Internet is available, resuming update");
if (mPendingUpdate) {
mScheduler.schedule(mFetchRunnable, 0, TimeUnit.SECONDS);
}
}
});
}
private class FetchGmsCertifiedProps implements Runnable {
@Override
public void run() {
if (!SystemProperties.getBoolean(SPOOF_PIXEL_PI, true)) {
mPendingUpdate = false;
return;
}
try {
dlog("FetchGmsCertifiedProps started");
if (!isInternetConnected()) {
Log.e(TAG, "Internet is unavailable, deferring update");
mPendingUpdate = true;
return;
}
mPendingUpdate = false;
String savedProps = readFromFile(mDataFile);
String props = fetchProps();
if (props != null && !savedProps.equals(props)) {
dlog("Found new props");
writeToFile(mDataFile, props);
dlog("FetchGmsCertifiedProps completed");
} else {
dlog("No change in props");
}
} catch (Exception e) {
Log.e(TAG, "Error in FetchGmsCertifiedProps", e);
}
}
}
}

View file

@ -163,6 +163,7 @@ import com.android.server.contextualsearch.ContextualSearchManagerService;
import com.android.server.coverage.CoverageService;
import com.android.server.cpu.CpuMonitorService;
import com.android.server.crashrecovery.CrashRecoveryAdaptor;
import com.android.server.crdroid.AttestationService;
import com.android.server.credentials.CredentialManagerService;
import com.android.server.criticalevents.CriticalEventLog;
import com.android.server.devicepolicy.DevicePolicyManagerService;
@ -2757,6 +2758,11 @@ public final class SystemServer implements Dumpable {
mSystemServiceManager.startService(BackgroundInstallControlService.class);
t.traceEnd();
}
// AttestationService
t.traceBegin("AttestationService");
mSystemServiceManager.startService(AttestationService.class);
t.traceEnd();
}
t.traceBegin("StartMediaProjectionManager");