Loading apex/jobscheduler/framework/java/com/android/server/usage/AppStandbyInternal.java +4 −2 Original line number Diff line number Diff line Loading @@ -5,6 +5,7 @@ import android.annotation.UserIdInt; import android.app.usage.AppStandbyInfo; import android.app.usage.UsageEvents; import android.app.usage.UsageStatsManager.StandbyBuckets; import android.app.usage.UsageStatsManager.SystemForcedReasons; import android.content.Context; import android.os.Looper; Loading Loading @@ -123,9 +124,10 @@ public interface AppStandbyInternal { * appropriate time. * * @param restrictReason The restrictReason for restricting the app. Should be one of the * UsageStatsManager.REASON_SUB_RESTRICT_* reasons. * UsageStatsManager.REASON_SUB_FORCED_SYSTEM_FLAG_* reasons. */ void restrictApp(@NonNull String packageName, int userId, int restrictReason); void restrictApp(@NonNull String packageName, int userId, @SystemForcedReasons int restrictReason); void addActiveDeviceAdmin(String adminPkg, int userId); Loading apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java +1 −1 Original line number Diff line number Diff line Loading @@ -974,7 +974,7 @@ public class JobSchedulerService extends com.android.server.SystemService if (!mQuotaTracker.isWithinQuota(userId, pkg, QUOTA_TRACKER_SCHEDULE_PERSISTED_TAG)) { Slog.e(TAG, userId + "-" + pkg + " has called schedule() too many times"); mAppStandbyInternal.restrictApp( pkg, userId, UsageStatsManager.REASON_SUB_RESTRICT_BUGGY); pkg, userId, UsageStatsManager.REASON_SUB_FORCED_SYSTEM_FLAG_BUGGY); if (mConstants.API_QUOTA_SCHEDULE_THROW_EXCEPTION) { final boolean isDebuggable; synchronized (mLock) { Loading apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java +29 −2 Original line number Diff line number Diff line Loading @@ -58,6 +58,7 @@ import android.app.AppGlobals; import android.app.usage.AppStandbyInfo; import android.app.usage.UsageEvents; import android.app.usage.UsageStatsManager.StandbyBuckets; import android.app.usage.UsageStatsManager.SystemForcedReasons; import android.appwidget.AppWidgetManager; import android.content.BroadcastReceiver; import android.content.ContentResolver; Loading Loading @@ -1153,6 +1154,13 @@ public class AppStandbyController implements AppStandbyInternal { } } @VisibleForTesting int getAppStandbyBucketReason(String packageName, int userId, long elapsedRealtime) { synchronized (mAppIdleLock) { return mAppIdleHistory.getAppStandbyReason(packageName, userId, elapsedRealtime); } } @Override public List<AppStandbyInfo> getAppStandbyBuckets(int userId) { synchronized (mAppIdleLock) { Loading @@ -1161,7 +1169,8 @@ public class AppStandbyController implements AppStandbyInternal { } @Override public void restrictApp(@NonNull String packageName, int userId, int restrictReason) { public void restrictApp(@NonNull String packageName, int userId, @SystemForcedReasons int restrictReason) { // If the package is not installed, don't allow the bucket to be set. if (!mInjector.isPackageInstalled(packageName, 0, userId)) { Slog.e(TAG, "Tried to restrict uninstalled app: " + packageName); Loading Loading @@ -1254,10 +1263,28 @@ public class AppStandbyController implements AppStandbyInternal { return; } final boolean wasForcedBySystem = (app.bucketingReason & REASON_MAIN_MASK) == REASON_MAIN_FORCED_BY_SYSTEM; // If the bucket was forced, don't allow prediction to override if (predicted && ((app.bucketingReason & REASON_MAIN_MASK) == REASON_MAIN_FORCED_BY_USER || (app.bucketingReason & REASON_MAIN_MASK) == REASON_MAIN_FORCED_BY_SYSTEM)) { || wasForcedBySystem)) { return; } final boolean isForcedBySystem = (reason & REASON_MAIN_MASK) == REASON_MAIN_FORCED_BY_SYSTEM; if (app.currentBucket == newBucket && wasForcedBySystem && isForcedBySystem) { mAppIdleHistory .noteRestrictionAttempt(packageName, userId, elapsedRealtime, reason); // Keep track of all restricting reasons reason = REASON_MAIN_FORCED_BY_SYSTEM | (app.bucketingReason & REASON_SUB_MASK) | (reason & REASON_SUB_MASK); mAppIdleHistory.setAppStandbyBucket(packageName, userId, elapsedRealtime, newBucket, reason, resetTimeout); return; } Loading core/java/android/app/usage/UsageStatsManager.java +21 −20 Original line number Diff line number Diff line Loading @@ -288,25 +288,25 @@ public final class UsageStatsManager { */ public static final int REASON_SUB_PREDICTED_RESTORED = 0x0001; /** * The reason for restricting the app is unknown or undefined. * The reason the system forced the app into the bucket is unknown or undefined. * @hide */ public static final int REASON_SUB_RESTRICT_UNDEFINED = 0x0000; public static final int REASON_SUB_FORCED_SYSTEM_FLAG_UNDEFINED = 0; /** * The app was unnecessarily using system resources (battery, memory, etc) in the background. * @hide */ public static final int REASON_SUB_RESTRICT_BACKGROUND_RESOURCE_USAGE = 0x0001; public static final int REASON_SUB_FORCED_SYSTEM_FLAG_BACKGROUND_RESOURCE_USAGE = 1 << 0; /** * The app was deemed to be intentionally abusive. * @hide */ public static final int REASON_SUB_RESTRICT_ABUSE = 0x0002; public static final int REASON_SUB_FORCED_SYSTEM_FLAG_ABUSE = 1 << 1; /** * The app was displaying buggy behavior. * @hide */ public static final int REASON_SUB_RESTRICT_BUGGY = 0x0003; public static final int REASON_SUB_FORCED_SYSTEM_FLAG_BUGGY = 1 << 2; /** @hide */ Loading @@ -322,6 +322,17 @@ public final class UsageStatsManager { @Retention(RetentionPolicy.SOURCE) public @interface StandbyBuckets {} /** @hide */ @IntDef(flag = true, prefix = {"REASON_SUB_FORCED_SYSTEM_FLAG_FLAG_"}, value = { REASON_SUB_FORCED_SYSTEM_FLAG_UNDEFINED, REASON_SUB_FORCED_SYSTEM_FLAG_BACKGROUND_RESOURCE_USAGE, REASON_SUB_FORCED_SYSTEM_FLAG_ABUSE, REASON_SUB_FORCED_SYSTEM_FLAG_BUGGY, }) @Retention(RetentionPolicy.SOURCE) public @interface SystemForcedReasons { } /** * Observer id of the registered observer for the group of packages that reached the usage * time limit. Included as an extra in the PendingIntent that was registered. Loading Loading @@ -1053,6 +1064,7 @@ public final class UsageStatsManager { /** @hide */ public static String reasonToString(int standbyReason) { final int subReason = standbyReason & REASON_SUB_MASK; StringBuilder sb = new StringBuilder(); switch (standbyReason & REASON_MAIN_MASK) { case REASON_MAIN_DEFAULT: Loading @@ -1060,19 +1072,8 @@ public final class UsageStatsManager { break; case REASON_MAIN_FORCED_BY_SYSTEM: sb.append("s"); switch (standbyReason & REASON_SUB_MASK) { case REASON_SUB_RESTRICT_ABUSE: sb.append("-ra"); break; case REASON_SUB_RESTRICT_BACKGROUND_RESOURCE_USAGE: sb.append("-rbru"); break; case REASON_SUB_RESTRICT_BUGGY: sb.append("-rb"); break; case REASON_SUB_RESTRICT_UNDEFINED: sb.append("-r"); break; if (subReason > 0) { sb.append("-").append(Integer.toBinaryString(subReason)); } break; case REASON_MAIN_FORCED_BY_USER: Loading @@ -1080,7 +1081,7 @@ public final class UsageStatsManager { break; case REASON_MAIN_PREDICTED: sb.append("p"); switch (standbyReason & REASON_SUB_MASK) { switch (subReason) { case REASON_SUB_PREDICTED_RESTORED: sb.append("-r"); break; Loading @@ -1091,7 +1092,7 @@ public final class UsageStatsManager { break; case REASON_MAIN_USAGE: sb.append("u"); switch (standbyReason & REASON_SUB_MASK) { switch (subReason) { case REASON_SUB_USAGE_SYSTEM_INTERACTION: sb.append("-si"); break; Loading services/tests/servicestests/src/com/android/server/usage/AppIdleHistoryTests.java +7 −4 Original line number Diff line number Diff line Loading @@ -20,7 +20,7 @@ import static android.app.usage.UsageStatsManager.REASON_MAIN_FORCED_BY_SYSTEM; import static android.app.usage.UsageStatsManager.REASON_MAIN_FORCED_BY_USER; import static android.app.usage.UsageStatsManager.REASON_MAIN_TIMEOUT; import static android.app.usage.UsageStatsManager.REASON_MAIN_USAGE; import static android.app.usage.UsageStatsManager.REASON_SUB_RESTRICT_BACKGROUND_RESOURCE_USAGE; import static android.app.usage.UsageStatsManager.REASON_SUB_FORCED_SYSTEM_FLAG_BACKGROUND_RESOURCE_USAGE; import static android.app.usage.UsageStatsManager.REASON_SUB_USAGE_MOVE_TO_FOREGROUND; import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_ACTIVE; import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_FREQUENT; Loading Loading @@ -103,7 +103,8 @@ public class AppIdleHistoryTests extends AndroidTestCase { aih.setAppStandbyBucket(PACKAGE_2, USER_ID, 2000, STANDBY_BUCKET_ACTIVE, REASON_MAIN_USAGE); aih.setAppStandbyBucket(PACKAGE_3, USER_ID, 2500, STANDBY_BUCKET_RESTRICTED, REASON_MAIN_FORCED_BY_SYSTEM | REASON_SUB_RESTRICT_BACKGROUND_RESOURCE_USAGE); REASON_MAIN_FORCED_BY_SYSTEM | REASON_SUB_FORCED_SYSTEM_FLAG_BACKGROUND_RESOURCE_USAGE); aih.setAppStandbyBucket(PACKAGE_4, USER_ID, 2750, STANDBY_BUCKET_RESTRICTED, REASON_MAIN_FORCED_BY_USER); aih.setAppStandbyBucket(PACKAGE_1, USER_ID, 3000, STANDBY_BUCKET_RARE, Loading @@ -114,7 +115,8 @@ public class AppIdleHistoryTests extends AndroidTestCase { assertEquals(aih.getAppStandbyReason(PACKAGE_1, USER_ID, 3000), REASON_MAIN_TIMEOUT); assertEquals(aih.getAppStandbyBucket(PACKAGE_3, USER_ID, 3000), STANDBY_BUCKET_RESTRICTED); assertEquals(aih.getAppStandbyReason(PACKAGE_3, USER_ID, 3000), REASON_MAIN_FORCED_BY_SYSTEM | REASON_SUB_RESTRICT_BACKGROUND_RESOURCE_USAGE); REASON_MAIN_FORCED_BY_SYSTEM | REASON_SUB_FORCED_SYSTEM_FLAG_BACKGROUND_RESOURCE_USAGE); assertEquals(aih.getAppStandbyReason(PACKAGE_4, USER_ID, 3000), REASON_MAIN_FORCED_BY_USER); Loading @@ -133,7 +135,8 @@ public class AppIdleHistoryTests extends AndroidTestCase { assertEquals(aih.getAppStandbyReason(PACKAGE_1, USER_ID, 5000), REASON_MAIN_TIMEOUT); assertEquals(aih.getAppStandbyBucket(PACKAGE_3, USER_ID, 3000), STANDBY_BUCKET_RESTRICTED); assertEquals(aih.getAppStandbyReason(PACKAGE_3, USER_ID, 3000), REASON_MAIN_FORCED_BY_SYSTEM | REASON_SUB_RESTRICT_BACKGROUND_RESOURCE_USAGE); REASON_MAIN_FORCED_BY_SYSTEM | REASON_SUB_FORCED_SYSTEM_FLAG_BACKGROUND_RESOURCE_USAGE); assertEquals(aih.getAppStandbyReason(PACKAGE_4, USER_ID, 3000), REASON_MAIN_FORCED_BY_USER); Loading Loading
apex/jobscheduler/framework/java/com/android/server/usage/AppStandbyInternal.java +4 −2 Original line number Diff line number Diff line Loading @@ -5,6 +5,7 @@ import android.annotation.UserIdInt; import android.app.usage.AppStandbyInfo; import android.app.usage.UsageEvents; import android.app.usage.UsageStatsManager.StandbyBuckets; import android.app.usage.UsageStatsManager.SystemForcedReasons; import android.content.Context; import android.os.Looper; Loading Loading @@ -123,9 +124,10 @@ public interface AppStandbyInternal { * appropriate time. * * @param restrictReason The restrictReason for restricting the app. Should be one of the * UsageStatsManager.REASON_SUB_RESTRICT_* reasons. * UsageStatsManager.REASON_SUB_FORCED_SYSTEM_FLAG_* reasons. */ void restrictApp(@NonNull String packageName, int userId, int restrictReason); void restrictApp(@NonNull String packageName, int userId, @SystemForcedReasons int restrictReason); void addActiveDeviceAdmin(String adminPkg, int userId); Loading
apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java +1 −1 Original line number Diff line number Diff line Loading @@ -974,7 +974,7 @@ public class JobSchedulerService extends com.android.server.SystemService if (!mQuotaTracker.isWithinQuota(userId, pkg, QUOTA_TRACKER_SCHEDULE_PERSISTED_TAG)) { Slog.e(TAG, userId + "-" + pkg + " has called schedule() too many times"); mAppStandbyInternal.restrictApp( pkg, userId, UsageStatsManager.REASON_SUB_RESTRICT_BUGGY); pkg, userId, UsageStatsManager.REASON_SUB_FORCED_SYSTEM_FLAG_BUGGY); if (mConstants.API_QUOTA_SCHEDULE_THROW_EXCEPTION) { final boolean isDebuggable; synchronized (mLock) { Loading
apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java +29 −2 Original line number Diff line number Diff line Loading @@ -58,6 +58,7 @@ import android.app.AppGlobals; import android.app.usage.AppStandbyInfo; import android.app.usage.UsageEvents; import android.app.usage.UsageStatsManager.StandbyBuckets; import android.app.usage.UsageStatsManager.SystemForcedReasons; import android.appwidget.AppWidgetManager; import android.content.BroadcastReceiver; import android.content.ContentResolver; Loading Loading @@ -1153,6 +1154,13 @@ public class AppStandbyController implements AppStandbyInternal { } } @VisibleForTesting int getAppStandbyBucketReason(String packageName, int userId, long elapsedRealtime) { synchronized (mAppIdleLock) { return mAppIdleHistory.getAppStandbyReason(packageName, userId, elapsedRealtime); } } @Override public List<AppStandbyInfo> getAppStandbyBuckets(int userId) { synchronized (mAppIdleLock) { Loading @@ -1161,7 +1169,8 @@ public class AppStandbyController implements AppStandbyInternal { } @Override public void restrictApp(@NonNull String packageName, int userId, int restrictReason) { public void restrictApp(@NonNull String packageName, int userId, @SystemForcedReasons int restrictReason) { // If the package is not installed, don't allow the bucket to be set. if (!mInjector.isPackageInstalled(packageName, 0, userId)) { Slog.e(TAG, "Tried to restrict uninstalled app: " + packageName); Loading Loading @@ -1254,10 +1263,28 @@ public class AppStandbyController implements AppStandbyInternal { return; } final boolean wasForcedBySystem = (app.bucketingReason & REASON_MAIN_MASK) == REASON_MAIN_FORCED_BY_SYSTEM; // If the bucket was forced, don't allow prediction to override if (predicted && ((app.bucketingReason & REASON_MAIN_MASK) == REASON_MAIN_FORCED_BY_USER || (app.bucketingReason & REASON_MAIN_MASK) == REASON_MAIN_FORCED_BY_SYSTEM)) { || wasForcedBySystem)) { return; } final boolean isForcedBySystem = (reason & REASON_MAIN_MASK) == REASON_MAIN_FORCED_BY_SYSTEM; if (app.currentBucket == newBucket && wasForcedBySystem && isForcedBySystem) { mAppIdleHistory .noteRestrictionAttempt(packageName, userId, elapsedRealtime, reason); // Keep track of all restricting reasons reason = REASON_MAIN_FORCED_BY_SYSTEM | (app.bucketingReason & REASON_SUB_MASK) | (reason & REASON_SUB_MASK); mAppIdleHistory.setAppStandbyBucket(packageName, userId, elapsedRealtime, newBucket, reason, resetTimeout); return; } Loading
core/java/android/app/usage/UsageStatsManager.java +21 −20 Original line number Diff line number Diff line Loading @@ -288,25 +288,25 @@ public final class UsageStatsManager { */ public static final int REASON_SUB_PREDICTED_RESTORED = 0x0001; /** * The reason for restricting the app is unknown or undefined. * The reason the system forced the app into the bucket is unknown or undefined. * @hide */ public static final int REASON_SUB_RESTRICT_UNDEFINED = 0x0000; public static final int REASON_SUB_FORCED_SYSTEM_FLAG_UNDEFINED = 0; /** * The app was unnecessarily using system resources (battery, memory, etc) in the background. * @hide */ public static final int REASON_SUB_RESTRICT_BACKGROUND_RESOURCE_USAGE = 0x0001; public static final int REASON_SUB_FORCED_SYSTEM_FLAG_BACKGROUND_RESOURCE_USAGE = 1 << 0; /** * The app was deemed to be intentionally abusive. * @hide */ public static final int REASON_SUB_RESTRICT_ABUSE = 0x0002; public static final int REASON_SUB_FORCED_SYSTEM_FLAG_ABUSE = 1 << 1; /** * The app was displaying buggy behavior. * @hide */ public static final int REASON_SUB_RESTRICT_BUGGY = 0x0003; public static final int REASON_SUB_FORCED_SYSTEM_FLAG_BUGGY = 1 << 2; /** @hide */ Loading @@ -322,6 +322,17 @@ public final class UsageStatsManager { @Retention(RetentionPolicy.SOURCE) public @interface StandbyBuckets {} /** @hide */ @IntDef(flag = true, prefix = {"REASON_SUB_FORCED_SYSTEM_FLAG_FLAG_"}, value = { REASON_SUB_FORCED_SYSTEM_FLAG_UNDEFINED, REASON_SUB_FORCED_SYSTEM_FLAG_BACKGROUND_RESOURCE_USAGE, REASON_SUB_FORCED_SYSTEM_FLAG_ABUSE, REASON_SUB_FORCED_SYSTEM_FLAG_BUGGY, }) @Retention(RetentionPolicy.SOURCE) public @interface SystemForcedReasons { } /** * Observer id of the registered observer for the group of packages that reached the usage * time limit. Included as an extra in the PendingIntent that was registered. Loading Loading @@ -1053,6 +1064,7 @@ public final class UsageStatsManager { /** @hide */ public static String reasonToString(int standbyReason) { final int subReason = standbyReason & REASON_SUB_MASK; StringBuilder sb = new StringBuilder(); switch (standbyReason & REASON_MAIN_MASK) { case REASON_MAIN_DEFAULT: Loading @@ -1060,19 +1072,8 @@ public final class UsageStatsManager { break; case REASON_MAIN_FORCED_BY_SYSTEM: sb.append("s"); switch (standbyReason & REASON_SUB_MASK) { case REASON_SUB_RESTRICT_ABUSE: sb.append("-ra"); break; case REASON_SUB_RESTRICT_BACKGROUND_RESOURCE_USAGE: sb.append("-rbru"); break; case REASON_SUB_RESTRICT_BUGGY: sb.append("-rb"); break; case REASON_SUB_RESTRICT_UNDEFINED: sb.append("-r"); break; if (subReason > 0) { sb.append("-").append(Integer.toBinaryString(subReason)); } break; case REASON_MAIN_FORCED_BY_USER: Loading @@ -1080,7 +1081,7 @@ public final class UsageStatsManager { break; case REASON_MAIN_PREDICTED: sb.append("p"); switch (standbyReason & REASON_SUB_MASK) { switch (subReason) { case REASON_SUB_PREDICTED_RESTORED: sb.append("-r"); break; Loading @@ -1091,7 +1092,7 @@ public final class UsageStatsManager { break; case REASON_MAIN_USAGE: sb.append("u"); switch (standbyReason & REASON_SUB_MASK) { switch (subReason) { case REASON_SUB_USAGE_SYSTEM_INTERACTION: sb.append("-si"); break; Loading
services/tests/servicestests/src/com/android/server/usage/AppIdleHistoryTests.java +7 −4 Original line number Diff line number Diff line Loading @@ -20,7 +20,7 @@ import static android.app.usage.UsageStatsManager.REASON_MAIN_FORCED_BY_SYSTEM; import static android.app.usage.UsageStatsManager.REASON_MAIN_FORCED_BY_USER; import static android.app.usage.UsageStatsManager.REASON_MAIN_TIMEOUT; import static android.app.usage.UsageStatsManager.REASON_MAIN_USAGE; import static android.app.usage.UsageStatsManager.REASON_SUB_RESTRICT_BACKGROUND_RESOURCE_USAGE; import static android.app.usage.UsageStatsManager.REASON_SUB_FORCED_SYSTEM_FLAG_BACKGROUND_RESOURCE_USAGE; import static android.app.usage.UsageStatsManager.REASON_SUB_USAGE_MOVE_TO_FOREGROUND; import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_ACTIVE; import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_FREQUENT; Loading Loading @@ -103,7 +103,8 @@ public class AppIdleHistoryTests extends AndroidTestCase { aih.setAppStandbyBucket(PACKAGE_2, USER_ID, 2000, STANDBY_BUCKET_ACTIVE, REASON_MAIN_USAGE); aih.setAppStandbyBucket(PACKAGE_3, USER_ID, 2500, STANDBY_BUCKET_RESTRICTED, REASON_MAIN_FORCED_BY_SYSTEM | REASON_SUB_RESTRICT_BACKGROUND_RESOURCE_USAGE); REASON_MAIN_FORCED_BY_SYSTEM | REASON_SUB_FORCED_SYSTEM_FLAG_BACKGROUND_RESOURCE_USAGE); aih.setAppStandbyBucket(PACKAGE_4, USER_ID, 2750, STANDBY_BUCKET_RESTRICTED, REASON_MAIN_FORCED_BY_USER); aih.setAppStandbyBucket(PACKAGE_1, USER_ID, 3000, STANDBY_BUCKET_RARE, Loading @@ -114,7 +115,8 @@ public class AppIdleHistoryTests extends AndroidTestCase { assertEquals(aih.getAppStandbyReason(PACKAGE_1, USER_ID, 3000), REASON_MAIN_TIMEOUT); assertEquals(aih.getAppStandbyBucket(PACKAGE_3, USER_ID, 3000), STANDBY_BUCKET_RESTRICTED); assertEquals(aih.getAppStandbyReason(PACKAGE_3, USER_ID, 3000), REASON_MAIN_FORCED_BY_SYSTEM | REASON_SUB_RESTRICT_BACKGROUND_RESOURCE_USAGE); REASON_MAIN_FORCED_BY_SYSTEM | REASON_SUB_FORCED_SYSTEM_FLAG_BACKGROUND_RESOURCE_USAGE); assertEquals(aih.getAppStandbyReason(PACKAGE_4, USER_ID, 3000), REASON_MAIN_FORCED_BY_USER); Loading @@ -133,7 +135,8 @@ public class AppIdleHistoryTests extends AndroidTestCase { assertEquals(aih.getAppStandbyReason(PACKAGE_1, USER_ID, 5000), REASON_MAIN_TIMEOUT); assertEquals(aih.getAppStandbyBucket(PACKAGE_3, USER_ID, 3000), STANDBY_BUCKET_RESTRICTED); assertEquals(aih.getAppStandbyReason(PACKAGE_3, USER_ID, 3000), REASON_MAIN_FORCED_BY_SYSTEM | REASON_SUB_RESTRICT_BACKGROUND_RESOURCE_USAGE); REASON_MAIN_FORCED_BY_SYSTEM | REASON_SUB_FORCED_SYSTEM_FLAG_BACKGROUND_RESOURCE_USAGE); assertEquals(aih.getAppStandbyReason(PACKAGE_4, USER_ID, 3000), REASON_MAIN_FORCED_BY_USER); Loading