Loading core/api/test-current.txt +1 −0 Original line number Original line Diff line number Diff line Loading @@ -50,6 +50,7 @@ package android { field public static final String SET_AND_VERIFY_LOCKSCREEN_CREDENTIALS = "android.permission.SET_AND_VERIFY_LOCKSCREEN_CREDENTIALS"; field public static final String SET_AND_VERIFY_LOCKSCREEN_CREDENTIALS = "android.permission.SET_AND_VERIFY_LOCKSCREEN_CREDENTIALS"; field public static final String SET_GAME_SERVICE = "android.permission.SET_GAME_SERVICE"; field public static final String SET_GAME_SERVICE = "android.permission.SET_GAME_SERVICE"; field public static final String SET_KEYBOARD_LAYOUT = "android.permission.SET_KEYBOARD_LAYOUT"; field public static final String SET_KEYBOARD_LAYOUT = "android.permission.SET_KEYBOARD_LAYOUT"; field public static final String START_ACTIVITIES_FROM_SDK_SANDBOX = "android.permission.START_ACTIVITIES_FROM_SDK_SANDBOX"; field public static final String SUSPEND_APPS = "android.permission.SUSPEND_APPS"; field public static final String SUSPEND_APPS = "android.permission.SUSPEND_APPS"; field public static final String TEST_BIOMETRIC = "android.permission.TEST_BIOMETRIC"; field public static final String TEST_BIOMETRIC = "android.permission.TEST_BIOMETRIC"; field public static final String TEST_INPUT_METHOD = "android.permission.TEST_INPUT_METHOD"; field public static final String TEST_INPUT_METHOD = "android.permission.TEST_INPUT_METHOD"; Loading core/java/android/app/ActivityThread.java +13 −1 Original line number Original line Diff line number Diff line Loading @@ -3720,7 +3720,19 @@ public final class ActivityThread extends ClientTransactionHandler /** Core implementation of activity launch. */ /** Core implementation of activity launch. */ private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) { private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) { ActivityInfo aInfo = r.activityInfo; ActivityInfo aInfo = r.activityInfo; if (r.packageInfo == null) { if (getInstrumentation() != null && getInstrumentation().getContext() != null && getInstrumentation().getContext().getApplicationInfo() != null && getInstrumentation().isSdkSandboxAllowedToStartActivities()) { // Activities launched from CTS-in-sandbox tests use a customized ApplicationInfo. See // also {@link SdkSandboxManagerLocal#getSdkSandboxApplicationInfoForInstrumentation}. r.packageInfo = getPackageInfo( getInstrumentation().getContext().getApplicationInfo(), mCompatibilityInfo, Context.CONTEXT_INCLUDE_CODE); } else if (r.packageInfo == null) { r.packageInfo = getPackageInfo(aInfo.applicationInfo, mCompatibilityInfo, r.packageInfo = getPackageInfo(aInfo.applicationInfo, mCompatibilityInfo, Context.CONTEXT_INCLUDE_CODE); Context.CONTEXT_INCLUDE_CODE); } } Loading core/java/android/app/Instrumentation.java +75 −2 Original line number Original line Diff line number Diff line Loading @@ -26,6 +26,7 @@ import android.content.Context; import android.content.Intent; import android.content.Intent; import android.content.IntentFilter; import android.content.IntentFilter; import android.content.pm.ActivityInfo; import android.content.pm.ActivityInfo; import android.content.pm.PackageManager; import android.content.res.Configuration; import android.content.res.Configuration; import android.hardware.input.InputManager; import android.hardware.input.InputManager; import android.hardware.input.InputManagerGlobal; import android.hardware.input.InputManagerGlobal; Loading Loading @@ -474,6 +475,56 @@ public class Instrumentation { sr.waitForComplete(); sr.waitForComplete(); } } boolean isSdkSandboxAllowedToStartActivities() { return Process.isSdkSandbox() && mThread != null && mThread.mBoundApplication != null && mThread.mBoundApplication.isSdkInSandbox && getContext() != null && (getContext() .checkSelfPermission( android.Manifest.permission .START_ACTIVITIES_FROM_SDK_SANDBOX) == PackageManager.PERMISSION_GRANTED); } /** * Activity name resolution for CTS-in-SdkSandbox tests requires some adjustments. Intents * generated using {@link Context#getPackageName()} use the SDK sandbox package name in the * component field instead of the test package name. An SDK-in-sandbox test attempting to launch * an activity in the test package will encounter name resolution errors when resolving the * activity name in the SDK sandbox package. * * <p>This function replaces the package name of the input intent component to allow activities * belonging to a CTS-in-sandbox test to resolve correctly. * * @param intent the intent to modify to allow CTS-in-sandbox activity resolution. */ private void adjustIntentForCtsInSdkSandboxInstrumentation(@NonNull Intent intent) { if (mComponent != null && intent.getComponent() != null && getContext() .getPackageManager() .getSdkSandboxPackageName() .equals(intent.getComponent().getPackageName())) { // Resolve the intent target for the test package, not for the sandbox package. intent.setComponent( new ComponentName( mComponent.getPackageName(), intent.getComponent().getClassName())); } // We match the intent identifier against the running instrumentations for the sandbox. intent.setIdentifier(mComponent.getPackageName()); } private ActivityInfo resolveActivityInfoForCtsInSandbox(@NonNull Intent intent) { adjustIntentForCtsInSdkSandboxInstrumentation(intent); ActivityInfo ai = intent.resolveActivityInfo(getTargetContext().getPackageManager(), 0); if (ai != null) { ai.processName = mThread.getProcessName(); } return ai; } /** /** * Start a new activity and wait for it to begin running before returning. * Start a new activity and wait for it to begin running before returning. * In addition to being synchronous, this method as some semantic * In addition to being synchronous, this method as some semantic Loading Loading @@ -531,8 +582,10 @@ public class Instrumentation { synchronized (mSync) { synchronized (mSync) { intent = new Intent(intent); intent = new Intent(intent); ActivityInfo ai = intent.resolveActivityInfo( ActivityInfo ai = getTargetContext().getPackageManager(), 0); isSdkSandboxAllowedToStartActivities() ? resolveActivityInfoForCtsInSandbox(intent) : intent.resolveActivityInfo(getTargetContext().getPackageManager(), 0); if (ai == null) { if (ai == null) { throw new RuntimeException("Unable to resolve activity for: " + intent); throw new RuntimeException("Unable to resolve activity for: " + intent); } } Loading Loading @@ -1842,6 +1895,9 @@ public class Instrumentation { if (referrer != null) { if (referrer != null) { intent.putExtra(Intent.EXTRA_REFERRER, referrer); intent.putExtra(Intent.EXTRA_REFERRER, referrer); } } if (isSdkSandboxAllowedToStartActivities()) { adjustIntentForCtsInSdkSandboxInstrumentation(intent); } if (mActivityMonitors != null) { if (mActivityMonitors != null) { synchronized (mSync) { synchronized (mSync) { final int N = mActivityMonitors.size(); final int N = mActivityMonitors.size(); Loading Loading @@ -1914,6 +1970,11 @@ public class Instrumentation { IBinder token, Activity target, Intent[] intents, Bundle options, IBinder token, Activity target, Intent[] intents, Bundle options, int userId) { int userId) { IApplicationThread whoThread = (IApplicationThread) contextThread; IApplicationThread whoThread = (IApplicationThread) contextThread; if (isSdkSandboxAllowedToStartActivities()) { for (Intent intent : intents) { adjustIntentForCtsInSdkSandboxInstrumentation(intent); } } if (mActivityMonitors != null) { if (mActivityMonitors != null) { synchronized (mSync) { synchronized (mSync) { final int N = mActivityMonitors.size(); final int N = mActivityMonitors.size(); Loading Loading @@ -1989,6 +2050,9 @@ public class Instrumentation { Context who, IBinder contextThread, IBinder token, String target, Context who, IBinder contextThread, IBinder token, String target, Intent intent, int requestCode, Bundle options) { Intent intent, int requestCode, Bundle options) { IApplicationThread whoThread = (IApplicationThread) contextThread; IApplicationThread whoThread = (IApplicationThread) contextThread; if (isSdkSandboxAllowedToStartActivities()) { adjustIntentForCtsInSdkSandboxInstrumentation(intent); } if (mActivityMonitors != null) { if (mActivityMonitors != null) { synchronized (mSync) { synchronized (mSync) { final int N = mActivityMonitors.size(); final int N = mActivityMonitors.size(); Loading Loading @@ -2060,6 +2124,9 @@ public class Instrumentation { Context who, IBinder contextThread, IBinder token, String resultWho, Context who, IBinder contextThread, IBinder token, String resultWho, Intent intent, int requestCode, Bundle options, UserHandle user) { Intent intent, int requestCode, Bundle options, UserHandle user) { IApplicationThread whoThread = (IApplicationThread) contextThread; IApplicationThread whoThread = (IApplicationThread) contextThread; if (isSdkSandboxAllowedToStartActivities()) { adjustIntentForCtsInSdkSandboxInstrumentation(intent); } if (mActivityMonitors != null) { if (mActivityMonitors != null) { synchronized (mSync) { synchronized (mSync) { final int N = mActivityMonitors.size(); final int N = mActivityMonitors.size(); Loading Loading @@ -2110,6 +2177,9 @@ public class Instrumentation { Intent intent, int requestCode, Bundle options, Intent intent, int requestCode, Bundle options, boolean ignoreTargetSecurity, int userId) { boolean ignoreTargetSecurity, int userId) { IApplicationThread whoThread = (IApplicationThread) contextThread; IApplicationThread whoThread = (IApplicationThread) contextThread; if (isSdkSandboxAllowedToStartActivities()) { adjustIntentForCtsInSdkSandboxInstrumentation(intent); } if (mActivityMonitors != null) { if (mActivityMonitors != null) { synchronized (mSync) { synchronized (mSync) { final int N = mActivityMonitors.size(); final int N = mActivityMonitors.size(); Loading Loading @@ -2161,6 +2231,9 @@ public class Instrumentation { Context who, IBinder contextThread, IAppTask appTask, Context who, IBinder contextThread, IAppTask appTask, Intent intent, Bundle options) { Intent intent, Bundle options) { IApplicationThread whoThread = (IApplicationThread) contextThread; IApplicationThread whoThread = (IApplicationThread) contextThread; if (isSdkSandboxAllowedToStartActivities()) { adjustIntentForCtsInSdkSandboxInstrumentation(intent); } if (mActivityMonitors != null) { if (mActivityMonitors != null) { synchronized (mSync) { synchronized (mSync) { final int N = mActivityMonitors.size(); final int N = mActivityMonitors.size(); Loading core/java/android/content/Intent.java +1 −0 Original line number Original line Diff line number Diff line Loading @@ -12516,6 +12516,7 @@ public class Intent implements Parcelable, Cloneable { return (mFlags & FLAG_ACTIVITY_NEW_DOCUMENT) == FLAG_ACTIVITY_NEW_DOCUMENT; return (mFlags & FLAG_ACTIVITY_NEW_DOCUMENT) == FLAG_ACTIVITY_NEW_DOCUMENT; } } // TODO(b/299109198): Refactor into the {@link SdkSandboxManagerLocal} /** @hide */ /** @hide */ public boolean isSandboxActivity(@NonNull Context context) { public boolean isSandboxActivity(@NonNull Context context) { if (mAction != null && mAction.equals(ACTION_START_SANDBOXED_ACTIVITY)) { if (mAction != null && mAction.equals(ACTION_START_SANDBOXED_ACTIVITY)) { core/res/AndroidManifest.xml +4 −0 Original line number Original line Diff line number Diff line Loading @@ -7663,6 +7663,10 @@ <permission android:name="android.permission.DELETE_STAGED_HEALTH_CONNECT_REMOTE_DATA" <permission android:name="android.permission.DELETE_STAGED_HEALTH_CONNECT_REMOTE_DATA" android:protectionLevel="signature" /> android:protectionLevel="signature" /> <!-- @hide @TestApi Allows tests running in CTS-in-sandbox mode to launch activities --> <permission android:name="android.permission.START_ACTIVITIES_FROM_SDK_SANDBOX" android:protectionLevel="signature" /> <!-- @SystemApi Allows the holder to call health connect migration APIs. <!-- @SystemApi Allows the holder to call health connect migration APIs. @hide --> @hide --> <permission android:name="android.permission.MIGRATE_HEALTH_CONNECT_DATA" <permission android:name="android.permission.MIGRATE_HEALTH_CONNECT_DATA" Loading Loading
core/api/test-current.txt +1 −0 Original line number Original line Diff line number Diff line Loading @@ -50,6 +50,7 @@ package android { field public static final String SET_AND_VERIFY_LOCKSCREEN_CREDENTIALS = "android.permission.SET_AND_VERIFY_LOCKSCREEN_CREDENTIALS"; field public static final String SET_AND_VERIFY_LOCKSCREEN_CREDENTIALS = "android.permission.SET_AND_VERIFY_LOCKSCREEN_CREDENTIALS"; field public static final String SET_GAME_SERVICE = "android.permission.SET_GAME_SERVICE"; field public static final String SET_GAME_SERVICE = "android.permission.SET_GAME_SERVICE"; field public static final String SET_KEYBOARD_LAYOUT = "android.permission.SET_KEYBOARD_LAYOUT"; field public static final String SET_KEYBOARD_LAYOUT = "android.permission.SET_KEYBOARD_LAYOUT"; field public static final String START_ACTIVITIES_FROM_SDK_SANDBOX = "android.permission.START_ACTIVITIES_FROM_SDK_SANDBOX"; field public static final String SUSPEND_APPS = "android.permission.SUSPEND_APPS"; field public static final String SUSPEND_APPS = "android.permission.SUSPEND_APPS"; field public static final String TEST_BIOMETRIC = "android.permission.TEST_BIOMETRIC"; field public static final String TEST_BIOMETRIC = "android.permission.TEST_BIOMETRIC"; field public static final String TEST_INPUT_METHOD = "android.permission.TEST_INPUT_METHOD"; field public static final String TEST_INPUT_METHOD = "android.permission.TEST_INPUT_METHOD"; Loading
core/java/android/app/ActivityThread.java +13 −1 Original line number Original line Diff line number Diff line Loading @@ -3720,7 +3720,19 @@ public final class ActivityThread extends ClientTransactionHandler /** Core implementation of activity launch. */ /** Core implementation of activity launch. */ private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) { private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) { ActivityInfo aInfo = r.activityInfo; ActivityInfo aInfo = r.activityInfo; if (r.packageInfo == null) { if (getInstrumentation() != null && getInstrumentation().getContext() != null && getInstrumentation().getContext().getApplicationInfo() != null && getInstrumentation().isSdkSandboxAllowedToStartActivities()) { // Activities launched from CTS-in-sandbox tests use a customized ApplicationInfo. See // also {@link SdkSandboxManagerLocal#getSdkSandboxApplicationInfoForInstrumentation}. r.packageInfo = getPackageInfo( getInstrumentation().getContext().getApplicationInfo(), mCompatibilityInfo, Context.CONTEXT_INCLUDE_CODE); } else if (r.packageInfo == null) { r.packageInfo = getPackageInfo(aInfo.applicationInfo, mCompatibilityInfo, r.packageInfo = getPackageInfo(aInfo.applicationInfo, mCompatibilityInfo, Context.CONTEXT_INCLUDE_CODE); Context.CONTEXT_INCLUDE_CODE); } } Loading
core/java/android/app/Instrumentation.java +75 −2 Original line number Original line Diff line number Diff line Loading @@ -26,6 +26,7 @@ import android.content.Context; import android.content.Intent; import android.content.Intent; import android.content.IntentFilter; import android.content.IntentFilter; import android.content.pm.ActivityInfo; import android.content.pm.ActivityInfo; import android.content.pm.PackageManager; import android.content.res.Configuration; import android.content.res.Configuration; import android.hardware.input.InputManager; import android.hardware.input.InputManager; import android.hardware.input.InputManagerGlobal; import android.hardware.input.InputManagerGlobal; Loading Loading @@ -474,6 +475,56 @@ public class Instrumentation { sr.waitForComplete(); sr.waitForComplete(); } } boolean isSdkSandboxAllowedToStartActivities() { return Process.isSdkSandbox() && mThread != null && mThread.mBoundApplication != null && mThread.mBoundApplication.isSdkInSandbox && getContext() != null && (getContext() .checkSelfPermission( android.Manifest.permission .START_ACTIVITIES_FROM_SDK_SANDBOX) == PackageManager.PERMISSION_GRANTED); } /** * Activity name resolution for CTS-in-SdkSandbox tests requires some adjustments. Intents * generated using {@link Context#getPackageName()} use the SDK sandbox package name in the * component field instead of the test package name. An SDK-in-sandbox test attempting to launch * an activity in the test package will encounter name resolution errors when resolving the * activity name in the SDK sandbox package. * * <p>This function replaces the package name of the input intent component to allow activities * belonging to a CTS-in-sandbox test to resolve correctly. * * @param intent the intent to modify to allow CTS-in-sandbox activity resolution. */ private void adjustIntentForCtsInSdkSandboxInstrumentation(@NonNull Intent intent) { if (mComponent != null && intent.getComponent() != null && getContext() .getPackageManager() .getSdkSandboxPackageName() .equals(intent.getComponent().getPackageName())) { // Resolve the intent target for the test package, not for the sandbox package. intent.setComponent( new ComponentName( mComponent.getPackageName(), intent.getComponent().getClassName())); } // We match the intent identifier against the running instrumentations for the sandbox. intent.setIdentifier(mComponent.getPackageName()); } private ActivityInfo resolveActivityInfoForCtsInSandbox(@NonNull Intent intent) { adjustIntentForCtsInSdkSandboxInstrumentation(intent); ActivityInfo ai = intent.resolveActivityInfo(getTargetContext().getPackageManager(), 0); if (ai != null) { ai.processName = mThread.getProcessName(); } return ai; } /** /** * Start a new activity and wait for it to begin running before returning. * Start a new activity and wait for it to begin running before returning. * In addition to being synchronous, this method as some semantic * In addition to being synchronous, this method as some semantic Loading Loading @@ -531,8 +582,10 @@ public class Instrumentation { synchronized (mSync) { synchronized (mSync) { intent = new Intent(intent); intent = new Intent(intent); ActivityInfo ai = intent.resolveActivityInfo( ActivityInfo ai = getTargetContext().getPackageManager(), 0); isSdkSandboxAllowedToStartActivities() ? resolveActivityInfoForCtsInSandbox(intent) : intent.resolveActivityInfo(getTargetContext().getPackageManager(), 0); if (ai == null) { if (ai == null) { throw new RuntimeException("Unable to resolve activity for: " + intent); throw new RuntimeException("Unable to resolve activity for: " + intent); } } Loading Loading @@ -1842,6 +1895,9 @@ public class Instrumentation { if (referrer != null) { if (referrer != null) { intent.putExtra(Intent.EXTRA_REFERRER, referrer); intent.putExtra(Intent.EXTRA_REFERRER, referrer); } } if (isSdkSandboxAllowedToStartActivities()) { adjustIntentForCtsInSdkSandboxInstrumentation(intent); } if (mActivityMonitors != null) { if (mActivityMonitors != null) { synchronized (mSync) { synchronized (mSync) { final int N = mActivityMonitors.size(); final int N = mActivityMonitors.size(); Loading Loading @@ -1914,6 +1970,11 @@ public class Instrumentation { IBinder token, Activity target, Intent[] intents, Bundle options, IBinder token, Activity target, Intent[] intents, Bundle options, int userId) { int userId) { IApplicationThread whoThread = (IApplicationThread) contextThread; IApplicationThread whoThread = (IApplicationThread) contextThread; if (isSdkSandboxAllowedToStartActivities()) { for (Intent intent : intents) { adjustIntentForCtsInSdkSandboxInstrumentation(intent); } } if (mActivityMonitors != null) { if (mActivityMonitors != null) { synchronized (mSync) { synchronized (mSync) { final int N = mActivityMonitors.size(); final int N = mActivityMonitors.size(); Loading Loading @@ -1989,6 +2050,9 @@ public class Instrumentation { Context who, IBinder contextThread, IBinder token, String target, Context who, IBinder contextThread, IBinder token, String target, Intent intent, int requestCode, Bundle options) { Intent intent, int requestCode, Bundle options) { IApplicationThread whoThread = (IApplicationThread) contextThread; IApplicationThread whoThread = (IApplicationThread) contextThread; if (isSdkSandboxAllowedToStartActivities()) { adjustIntentForCtsInSdkSandboxInstrumentation(intent); } if (mActivityMonitors != null) { if (mActivityMonitors != null) { synchronized (mSync) { synchronized (mSync) { final int N = mActivityMonitors.size(); final int N = mActivityMonitors.size(); Loading Loading @@ -2060,6 +2124,9 @@ public class Instrumentation { Context who, IBinder contextThread, IBinder token, String resultWho, Context who, IBinder contextThread, IBinder token, String resultWho, Intent intent, int requestCode, Bundle options, UserHandle user) { Intent intent, int requestCode, Bundle options, UserHandle user) { IApplicationThread whoThread = (IApplicationThread) contextThread; IApplicationThread whoThread = (IApplicationThread) contextThread; if (isSdkSandboxAllowedToStartActivities()) { adjustIntentForCtsInSdkSandboxInstrumentation(intent); } if (mActivityMonitors != null) { if (mActivityMonitors != null) { synchronized (mSync) { synchronized (mSync) { final int N = mActivityMonitors.size(); final int N = mActivityMonitors.size(); Loading Loading @@ -2110,6 +2177,9 @@ public class Instrumentation { Intent intent, int requestCode, Bundle options, Intent intent, int requestCode, Bundle options, boolean ignoreTargetSecurity, int userId) { boolean ignoreTargetSecurity, int userId) { IApplicationThread whoThread = (IApplicationThread) contextThread; IApplicationThread whoThread = (IApplicationThread) contextThread; if (isSdkSandboxAllowedToStartActivities()) { adjustIntentForCtsInSdkSandboxInstrumentation(intent); } if (mActivityMonitors != null) { if (mActivityMonitors != null) { synchronized (mSync) { synchronized (mSync) { final int N = mActivityMonitors.size(); final int N = mActivityMonitors.size(); Loading Loading @@ -2161,6 +2231,9 @@ public class Instrumentation { Context who, IBinder contextThread, IAppTask appTask, Context who, IBinder contextThread, IAppTask appTask, Intent intent, Bundle options) { Intent intent, Bundle options) { IApplicationThread whoThread = (IApplicationThread) contextThread; IApplicationThread whoThread = (IApplicationThread) contextThread; if (isSdkSandboxAllowedToStartActivities()) { adjustIntentForCtsInSdkSandboxInstrumentation(intent); } if (mActivityMonitors != null) { if (mActivityMonitors != null) { synchronized (mSync) { synchronized (mSync) { final int N = mActivityMonitors.size(); final int N = mActivityMonitors.size(); Loading
core/java/android/content/Intent.java +1 −0 Original line number Original line Diff line number Diff line Loading @@ -12516,6 +12516,7 @@ public class Intent implements Parcelable, Cloneable { return (mFlags & FLAG_ACTIVITY_NEW_DOCUMENT) == FLAG_ACTIVITY_NEW_DOCUMENT; return (mFlags & FLAG_ACTIVITY_NEW_DOCUMENT) == FLAG_ACTIVITY_NEW_DOCUMENT; } } // TODO(b/299109198): Refactor into the {@link SdkSandboxManagerLocal} /** @hide */ /** @hide */ public boolean isSandboxActivity(@NonNull Context context) { public boolean isSandboxActivity(@NonNull Context context) { if (mAction != null && mAction.equals(ACTION_START_SANDBOXED_ACTIVITY)) { if (mAction != null && mAction.equals(ACTION_START_SANDBOXED_ACTIVITY)) {
core/res/AndroidManifest.xml +4 −0 Original line number Original line Diff line number Diff line Loading @@ -7663,6 +7663,10 @@ <permission android:name="android.permission.DELETE_STAGED_HEALTH_CONNECT_REMOTE_DATA" <permission android:name="android.permission.DELETE_STAGED_HEALTH_CONNECT_REMOTE_DATA" android:protectionLevel="signature" /> android:protectionLevel="signature" /> <!-- @hide @TestApi Allows tests running in CTS-in-sandbox mode to launch activities --> <permission android:name="android.permission.START_ACTIVITIES_FROM_SDK_SANDBOX" android:protectionLevel="signature" /> <!-- @SystemApi Allows the holder to call health connect migration APIs. <!-- @SystemApi Allows the holder to call health connect migration APIs. @hide --> @hide --> <permission android:name="android.permission.MIGRATE_HEALTH_CONNECT_DATA" <permission android:name="android.permission.MIGRATE_HEALTH_CONNECT_DATA" Loading