Loading apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java +13 −3 Original line number Diff line number Diff line Loading @@ -1433,10 +1433,10 @@ public class JobSchedulerService extends com.android.server.SystemService Slog.d(TAG, "Removing jobs for pkg " + pkgName + " at uid " + pkgUid); } synchronized (mLock) { // Exclude jobs scheduled on behalf of this app for now because SyncManager // Exclude jobs scheduled on behalf of this app because SyncManager // and other job proxy agents may not know to reschedule the job properly // after force stop. // TODO(209852664): determine how to best handle syncs & other proxied jobs // Proxied jobs will not be allowed to run if the source app is stopped. cancelJobsForPackageAndUidLocked(pkgName, pkgUid, /* includeSchedulingApp */ true, /* includeSourceApp */ false, JobParameters.STOP_REASON_USER, Loading @@ -1448,7 +1448,9 @@ public class JobSchedulerService extends com.android.server.SystemService } }; private String getPackageName(Intent intent) { /** Returns the package name stored in the intent's data. */ @Nullable public static String getPackageName(Intent intent) { Uri uri = intent.getData(); String pkg = uri != null ? uri.getSchemeSpecificPart() : null; return pkg; Loading Loading @@ -5365,6 +5367,14 @@ public class JobSchedulerService extends com.android.server.SystemService } pw.println(); pw.println("Aconfig flags:"); pw.increaseIndent(); pw.print(Flags.FLAG_THROW_ON_UNSUPPORTED_BIAS_USAGE, Flags.throwOnUnsupportedBiasUsage()); pw.println(); pw.decreaseIndent(); pw.println(); for (int i = mJobRestrictions.size() - 1; i >= 0; i--) { mJobRestrictions.get(i).dumpConstants(pw); } Loading apex/jobscheduler/service/java/com/android/server/job/JobSchedulerShellCommand.java +27 −0 Original line number Diff line number Diff line Loading @@ -58,6 +58,8 @@ public final class JobSchedulerShellCommand extends BasicShellCommandHandler { return cancelJob(pw); case "monitor-battery": return monitorBattery(pw); case "get-aconfig-flag-state": return getAconfigFlagState(pw); case "get-battery-seq": return getBatterySeq(pw); case "get-battery-charging": Loading Loading @@ -336,6 +338,28 @@ public final class JobSchedulerShellCommand extends BasicShellCommandHandler { return 0; } private int getAconfigFlagState(PrintWriter pw) throws Exception { checkPermission("get aconfig flag state"); final String flagName = getNextArgRequired(); switch (flagName) { case android.app.job.Flags.FLAG_JOB_DEBUG_INFO_APIS: pw.println(android.app.job.Flags.jobDebugInfoApis()); break; case android.app.job.Flags.FLAG_ENFORCE_MINIMUM_TIME_WINDOWS: pw.println(android.app.job.Flags.enforceMinimumTimeWindows()); break; case com.android.server.job.Flags.FLAG_THROW_ON_UNSUPPORTED_BIAS_USAGE: pw.println(com.android.server.job.Flags.throwOnUnsupportedBiasUsage()); break; default: pw.println("Unknown flag: " + flagName); break; } return 0; } private int getBatterySeq(PrintWriter pw) { int seq = mInternal.getBatterySeq(); pw.println(seq); Loading Loading @@ -693,6 +717,9 @@ public final class JobSchedulerShellCommand extends BasicShellCommandHandler { pw.println(" monitor-battery [on|off]"); pw.println(" Control monitoring of all battery changes. Off by default. Turning"); pw.println(" on makes get-battery-seq useful."); pw.println(" get-aconfig-flag-state FULL_FLAG_NAME"); pw.println(" Return the state of the specified aconfig flag, if known. The flag name"); pw.println(" must be fully qualified."); pw.println(" get-battery-seq"); pw.println(" Return the last battery update sequence number that was received."); pw.println(" get-battery-charging"); Loading apex/jobscheduler/service/java/com/android/server/job/controllers/BackgroundJobsController.java +115 −4 Original line number Diff line number Diff line Loading @@ -17,18 +17,26 @@ package com.android.server.job.controllers; import static com.android.server.job.JobSchedulerService.NEVER_INDEX; import static com.android.server.job.JobSchedulerService.getPackageName; import static com.android.server.job.JobSchedulerService.sElapsedRealtimeClock; import android.app.ActivityManager; import android.app.ActivityManagerInternal; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.PackageManagerInternal; import android.os.SystemClock; import android.os.UserHandle; import android.util.ArraySet; import android.util.IndentingPrintWriter; import android.util.Log; import android.util.Slog; import android.util.SparseArrayMap; import android.util.proto.ProtoOutputStream; import com.android.internal.annotations.GuardedBy; import com.android.server.AppStateTracker; import com.android.server.AppStateTrackerImpl; import com.android.server.AppStateTrackerImpl.Listener; Loading @@ -50,6 +58,8 @@ import java.util.function.Predicate; * * - the uid-active boolean state expressed by the AppStateTracker. Jobs in 'active' * uids are inherently eligible to run jobs regardless of the uid's standby bucket. * * - the app's stopped state */ public final class BackgroundJobsController extends StateController { private static final String TAG = "JobScheduler.Background"; Loading @@ -63,9 +73,48 @@ public final class BackgroundJobsController extends StateController { private final ActivityManagerInternal mActivityManagerInternal; private final AppStateTrackerImpl mAppStateTracker; private final PackageManagerInternal mPackageManagerInternal; @GuardedBy("mLock") private final SparseArrayMap<String, Boolean> mPackageStoppedState = new SparseArrayMap<>(); private final UpdateJobFunctor mUpdateJobFunctor = new UpdateJobFunctor(); private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { final String pkgName = getPackageName(intent); final int pkgUid = intent.getIntExtra(Intent.EXTRA_UID, -1); final String action = intent.getAction(); if (pkgUid == -1) { Slog.e(TAG, "Didn't get package UID in intent (" + action + ")"); return; } if (DEBUG) { Slog.d(TAG, "Got " + action + " for " + pkgUid + "/" + pkgName); } switch (action) { case Intent.ACTION_PACKAGE_RESTARTED: { synchronized (mLock) { mPackageStoppedState.add(pkgUid, pkgName, Boolean.TRUE); updateJobRestrictionsForUidLocked(pkgUid, false); } } break; case Intent.ACTION_PACKAGE_UNSTOPPED: { synchronized (mLock) { mPackageStoppedState.add(pkgUid, pkgName, Boolean.FALSE); updateJobRestrictionsLocked(pkgUid, UNKNOWN); } } break; } } }; public BackgroundJobsController(JobSchedulerService service) { super(service); Loading @@ -73,11 +122,18 @@ public final class BackgroundJobsController extends StateController { LocalServices.getService(ActivityManagerInternal.class)); mAppStateTracker = (AppStateTrackerImpl) Objects.requireNonNull( LocalServices.getService(AppStateTracker.class)); mPackageManagerInternal = LocalServices.getService(PackageManagerInternal.class); } @Override public void startTrackingLocked() { mAppStateTracker.addListener(mForceAppStandbyListener); final IntentFilter filter = new IntentFilter(); filter.addAction(Intent.ACTION_PACKAGE_RESTARTED); filter.addAction(Intent.ACTION_PACKAGE_UNSTOPPED); filter.addDataScheme("package"); mContext.registerReceiverAsUser( mBroadcastReceiver, UserHandle.ALL, filter, null, null); } @Override Loading @@ -98,12 +154,46 @@ public final class BackgroundJobsController extends StateController { } } @Override public void onAppRemovedLocked(String packageName, int uid) { mPackageStoppedState.delete(uid, packageName); } @Override public void onUserRemovedLocked(int userId) { for (int u = mPackageStoppedState.numMaps() - 1; u >= 0; --u) { final int uid = mPackageStoppedState.keyAt(u); if (UserHandle.getUserId(uid) == userId) { mPackageStoppedState.deleteAt(u); } } } @Override public void dumpControllerStateLocked(final IndentingPrintWriter pw, final Predicate<JobStatus> predicate) { pw.println("Aconfig flags:"); pw.increaseIndent(); pw.print(android.content.pm.Flags.FLAG_STAY_STOPPED, android.content.pm.Flags.stayStopped()); pw.println(); pw.decreaseIndent(); pw.println(); mAppStateTracker.dump(pw); pw.println(); pw.println("Stopped packages:"); pw.increaseIndent(); mPackageStoppedState.forEach((uid, pkgName, isStopped) -> { pw.print(uid); pw.print(":"); pw.print(pkgName); pw.print("="); pw.println(isStopped); }); pw.println(); mService.getJobStore().forEachJob(predicate, (jobStatus) -> { final int uid = jobStatus.getSourceUid(); final String sourcePkg = jobStatus.getSourcePackageName(); Loading Loading @@ -205,14 +295,34 @@ public final class BackgroundJobsController extends StateController { } } private boolean isPackageStopped(String packageName, int uid) { if (mPackageStoppedState.contains(uid, packageName)) { return mPackageStoppedState.get(uid, packageName); } final boolean isStopped = mPackageManagerInternal.isPackageStopped(packageName, uid); mPackageStoppedState.add(uid, packageName, isStopped); return isStopped; } boolean updateSingleJobRestrictionLocked(JobStatus jobStatus, final long nowElapsed, int activeState) { final int uid = jobStatus.getSourceUid(); final String packageName = jobStatus.getSourcePackageName(); final boolean isUserBgRestricted = !mActivityManagerInternal.isBgAutoRestrictedBucketFeatureFlagEnabled() && !mAppStateTracker.isRunAnyInBackgroundAppOpsAllowed(uid, packageName); final boolean isSourcePkgStopped = isPackageStopped(jobStatus.getSourcePackageName(), jobStatus.getSourceUid()); final boolean isCallingPkgStopped; if (!jobStatus.isProxyJob()) { isCallingPkgStopped = isSourcePkgStopped; } else { isCallingPkgStopped = isPackageStopped(jobStatus.getCallingPackageName(), jobStatus.getUid()); } final boolean isStopped = android.content.pm.Flags.stayStopped() && (isCallingPkgStopped || isSourcePkgStopped); final boolean isUserBgRestricted = isStopped || (!mActivityManagerInternal.isBgAutoRestrictedBucketFeatureFlagEnabled() && !mAppStateTracker.isRunAnyInBackgroundAppOpsAllowed(uid, packageName)); // If a job started with the foreground flag, it'll cause the UID to stay active // and thus cause areJobsRestricted() to always return false, so if // areJobsRestricted() returns false and the app is BG restricted and not TOP, Loading @@ -233,7 +343,8 @@ public final class BackgroundJobsController extends StateController { && isUserBgRestricted && mService.getUidProcState(uid) > ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE; final boolean canRun = !shouldStopImmediately // Don't let jobs (including proxied jobs) run if the app is in the stopped state. final boolean canRun = !isStopped && !shouldStopImmediately && !mAppStateTracker.areJobsRestricted( uid, packageName, jobStatus.canRunInBatterySaver()); Loading apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java +6 −0 Original line number Diff line number Diff line Loading @@ -1102,6 +1102,12 @@ public final class JobStatus { return job.getService(); } /** Return the package name of the app that scheduled the job. */ public String getCallingPackageName() { return job.getService().getPackageName(); } /** Return the package name of the app on whose behalf the job was scheduled. */ public String getSourcePackageName() { return sourcePackageName; } Loading cmds/idmap2/Android.bp +5 −0 Original line number Diff line number Diff line Loading @@ -86,6 +86,7 @@ cc_library { static_libs: [ "libidmap2_policies", "libidmap2_protos", "libpng", ], shared_libs: [ "libandroidfw", Loading @@ -107,6 +108,7 @@ cc_library { "libcutils", "libidmap2_policies", "libidmap2_protos", "libpng", "libprotobuf-cpp-lite", "libutils", "libz", Loading Loading @@ -185,6 +187,7 @@ cc_test { static_libs: [ "libgmock", "libidmap2_protos", "libpng", ], target: { android: { Loading Loading @@ -258,6 +261,7 @@ cc_binary { "libbase", "libcutils", "libidmap2", "libpng", "libprotobuf-cpp-lite", "libutils", "libz", Loading @@ -275,6 +279,7 @@ cc_binary { "libidmap2", "libidmap2_policies", "liblog", "libpng", "libprotobuf-cpp-lite", "libutils", "libziparchive", Loading Loading
apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java +13 −3 Original line number Diff line number Diff line Loading @@ -1433,10 +1433,10 @@ public class JobSchedulerService extends com.android.server.SystemService Slog.d(TAG, "Removing jobs for pkg " + pkgName + " at uid " + pkgUid); } synchronized (mLock) { // Exclude jobs scheduled on behalf of this app for now because SyncManager // Exclude jobs scheduled on behalf of this app because SyncManager // and other job proxy agents may not know to reschedule the job properly // after force stop. // TODO(209852664): determine how to best handle syncs & other proxied jobs // Proxied jobs will not be allowed to run if the source app is stopped. cancelJobsForPackageAndUidLocked(pkgName, pkgUid, /* includeSchedulingApp */ true, /* includeSourceApp */ false, JobParameters.STOP_REASON_USER, Loading @@ -1448,7 +1448,9 @@ public class JobSchedulerService extends com.android.server.SystemService } }; private String getPackageName(Intent intent) { /** Returns the package name stored in the intent's data. */ @Nullable public static String getPackageName(Intent intent) { Uri uri = intent.getData(); String pkg = uri != null ? uri.getSchemeSpecificPart() : null; return pkg; Loading Loading @@ -5365,6 +5367,14 @@ public class JobSchedulerService extends com.android.server.SystemService } pw.println(); pw.println("Aconfig flags:"); pw.increaseIndent(); pw.print(Flags.FLAG_THROW_ON_UNSUPPORTED_BIAS_USAGE, Flags.throwOnUnsupportedBiasUsage()); pw.println(); pw.decreaseIndent(); pw.println(); for (int i = mJobRestrictions.size() - 1; i >= 0; i--) { mJobRestrictions.get(i).dumpConstants(pw); } Loading
apex/jobscheduler/service/java/com/android/server/job/JobSchedulerShellCommand.java +27 −0 Original line number Diff line number Diff line Loading @@ -58,6 +58,8 @@ public final class JobSchedulerShellCommand extends BasicShellCommandHandler { return cancelJob(pw); case "monitor-battery": return monitorBattery(pw); case "get-aconfig-flag-state": return getAconfigFlagState(pw); case "get-battery-seq": return getBatterySeq(pw); case "get-battery-charging": Loading Loading @@ -336,6 +338,28 @@ public final class JobSchedulerShellCommand extends BasicShellCommandHandler { return 0; } private int getAconfigFlagState(PrintWriter pw) throws Exception { checkPermission("get aconfig flag state"); final String flagName = getNextArgRequired(); switch (flagName) { case android.app.job.Flags.FLAG_JOB_DEBUG_INFO_APIS: pw.println(android.app.job.Flags.jobDebugInfoApis()); break; case android.app.job.Flags.FLAG_ENFORCE_MINIMUM_TIME_WINDOWS: pw.println(android.app.job.Flags.enforceMinimumTimeWindows()); break; case com.android.server.job.Flags.FLAG_THROW_ON_UNSUPPORTED_BIAS_USAGE: pw.println(com.android.server.job.Flags.throwOnUnsupportedBiasUsage()); break; default: pw.println("Unknown flag: " + flagName); break; } return 0; } private int getBatterySeq(PrintWriter pw) { int seq = mInternal.getBatterySeq(); pw.println(seq); Loading Loading @@ -693,6 +717,9 @@ public final class JobSchedulerShellCommand extends BasicShellCommandHandler { pw.println(" monitor-battery [on|off]"); pw.println(" Control monitoring of all battery changes. Off by default. Turning"); pw.println(" on makes get-battery-seq useful."); pw.println(" get-aconfig-flag-state FULL_FLAG_NAME"); pw.println(" Return the state of the specified aconfig flag, if known. The flag name"); pw.println(" must be fully qualified."); pw.println(" get-battery-seq"); pw.println(" Return the last battery update sequence number that was received."); pw.println(" get-battery-charging"); Loading
apex/jobscheduler/service/java/com/android/server/job/controllers/BackgroundJobsController.java +115 −4 Original line number Diff line number Diff line Loading @@ -17,18 +17,26 @@ package com.android.server.job.controllers; import static com.android.server.job.JobSchedulerService.NEVER_INDEX; import static com.android.server.job.JobSchedulerService.getPackageName; import static com.android.server.job.JobSchedulerService.sElapsedRealtimeClock; import android.app.ActivityManager; import android.app.ActivityManagerInternal; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.PackageManagerInternal; import android.os.SystemClock; import android.os.UserHandle; import android.util.ArraySet; import android.util.IndentingPrintWriter; import android.util.Log; import android.util.Slog; import android.util.SparseArrayMap; import android.util.proto.ProtoOutputStream; import com.android.internal.annotations.GuardedBy; import com.android.server.AppStateTracker; import com.android.server.AppStateTrackerImpl; import com.android.server.AppStateTrackerImpl.Listener; Loading @@ -50,6 +58,8 @@ import java.util.function.Predicate; * * - the uid-active boolean state expressed by the AppStateTracker. Jobs in 'active' * uids are inherently eligible to run jobs regardless of the uid's standby bucket. * * - the app's stopped state */ public final class BackgroundJobsController extends StateController { private static final String TAG = "JobScheduler.Background"; Loading @@ -63,9 +73,48 @@ public final class BackgroundJobsController extends StateController { private final ActivityManagerInternal mActivityManagerInternal; private final AppStateTrackerImpl mAppStateTracker; private final PackageManagerInternal mPackageManagerInternal; @GuardedBy("mLock") private final SparseArrayMap<String, Boolean> mPackageStoppedState = new SparseArrayMap<>(); private final UpdateJobFunctor mUpdateJobFunctor = new UpdateJobFunctor(); private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { final String pkgName = getPackageName(intent); final int pkgUid = intent.getIntExtra(Intent.EXTRA_UID, -1); final String action = intent.getAction(); if (pkgUid == -1) { Slog.e(TAG, "Didn't get package UID in intent (" + action + ")"); return; } if (DEBUG) { Slog.d(TAG, "Got " + action + " for " + pkgUid + "/" + pkgName); } switch (action) { case Intent.ACTION_PACKAGE_RESTARTED: { synchronized (mLock) { mPackageStoppedState.add(pkgUid, pkgName, Boolean.TRUE); updateJobRestrictionsForUidLocked(pkgUid, false); } } break; case Intent.ACTION_PACKAGE_UNSTOPPED: { synchronized (mLock) { mPackageStoppedState.add(pkgUid, pkgName, Boolean.FALSE); updateJobRestrictionsLocked(pkgUid, UNKNOWN); } } break; } } }; public BackgroundJobsController(JobSchedulerService service) { super(service); Loading @@ -73,11 +122,18 @@ public final class BackgroundJobsController extends StateController { LocalServices.getService(ActivityManagerInternal.class)); mAppStateTracker = (AppStateTrackerImpl) Objects.requireNonNull( LocalServices.getService(AppStateTracker.class)); mPackageManagerInternal = LocalServices.getService(PackageManagerInternal.class); } @Override public void startTrackingLocked() { mAppStateTracker.addListener(mForceAppStandbyListener); final IntentFilter filter = new IntentFilter(); filter.addAction(Intent.ACTION_PACKAGE_RESTARTED); filter.addAction(Intent.ACTION_PACKAGE_UNSTOPPED); filter.addDataScheme("package"); mContext.registerReceiverAsUser( mBroadcastReceiver, UserHandle.ALL, filter, null, null); } @Override Loading @@ -98,12 +154,46 @@ public final class BackgroundJobsController extends StateController { } } @Override public void onAppRemovedLocked(String packageName, int uid) { mPackageStoppedState.delete(uid, packageName); } @Override public void onUserRemovedLocked(int userId) { for (int u = mPackageStoppedState.numMaps() - 1; u >= 0; --u) { final int uid = mPackageStoppedState.keyAt(u); if (UserHandle.getUserId(uid) == userId) { mPackageStoppedState.deleteAt(u); } } } @Override public void dumpControllerStateLocked(final IndentingPrintWriter pw, final Predicate<JobStatus> predicate) { pw.println("Aconfig flags:"); pw.increaseIndent(); pw.print(android.content.pm.Flags.FLAG_STAY_STOPPED, android.content.pm.Flags.stayStopped()); pw.println(); pw.decreaseIndent(); pw.println(); mAppStateTracker.dump(pw); pw.println(); pw.println("Stopped packages:"); pw.increaseIndent(); mPackageStoppedState.forEach((uid, pkgName, isStopped) -> { pw.print(uid); pw.print(":"); pw.print(pkgName); pw.print("="); pw.println(isStopped); }); pw.println(); mService.getJobStore().forEachJob(predicate, (jobStatus) -> { final int uid = jobStatus.getSourceUid(); final String sourcePkg = jobStatus.getSourcePackageName(); Loading Loading @@ -205,14 +295,34 @@ public final class BackgroundJobsController extends StateController { } } private boolean isPackageStopped(String packageName, int uid) { if (mPackageStoppedState.contains(uid, packageName)) { return mPackageStoppedState.get(uid, packageName); } final boolean isStopped = mPackageManagerInternal.isPackageStopped(packageName, uid); mPackageStoppedState.add(uid, packageName, isStopped); return isStopped; } boolean updateSingleJobRestrictionLocked(JobStatus jobStatus, final long nowElapsed, int activeState) { final int uid = jobStatus.getSourceUid(); final String packageName = jobStatus.getSourcePackageName(); final boolean isUserBgRestricted = !mActivityManagerInternal.isBgAutoRestrictedBucketFeatureFlagEnabled() && !mAppStateTracker.isRunAnyInBackgroundAppOpsAllowed(uid, packageName); final boolean isSourcePkgStopped = isPackageStopped(jobStatus.getSourcePackageName(), jobStatus.getSourceUid()); final boolean isCallingPkgStopped; if (!jobStatus.isProxyJob()) { isCallingPkgStopped = isSourcePkgStopped; } else { isCallingPkgStopped = isPackageStopped(jobStatus.getCallingPackageName(), jobStatus.getUid()); } final boolean isStopped = android.content.pm.Flags.stayStopped() && (isCallingPkgStopped || isSourcePkgStopped); final boolean isUserBgRestricted = isStopped || (!mActivityManagerInternal.isBgAutoRestrictedBucketFeatureFlagEnabled() && !mAppStateTracker.isRunAnyInBackgroundAppOpsAllowed(uid, packageName)); // If a job started with the foreground flag, it'll cause the UID to stay active // and thus cause areJobsRestricted() to always return false, so if // areJobsRestricted() returns false and the app is BG restricted and not TOP, Loading @@ -233,7 +343,8 @@ public final class BackgroundJobsController extends StateController { && isUserBgRestricted && mService.getUidProcState(uid) > ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE; final boolean canRun = !shouldStopImmediately // Don't let jobs (including proxied jobs) run if the app is in the stopped state. final boolean canRun = !isStopped && !shouldStopImmediately && !mAppStateTracker.areJobsRestricted( uid, packageName, jobStatus.canRunInBatterySaver()); Loading
apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java +6 −0 Original line number Diff line number Diff line Loading @@ -1102,6 +1102,12 @@ public final class JobStatus { return job.getService(); } /** Return the package name of the app that scheduled the job. */ public String getCallingPackageName() { return job.getService().getPackageName(); } /** Return the package name of the app on whose behalf the job was scheduled. */ public String getSourcePackageName() { return sourcePackageName; } Loading
cmds/idmap2/Android.bp +5 −0 Original line number Diff line number Diff line Loading @@ -86,6 +86,7 @@ cc_library { static_libs: [ "libidmap2_policies", "libidmap2_protos", "libpng", ], shared_libs: [ "libandroidfw", Loading @@ -107,6 +108,7 @@ cc_library { "libcutils", "libidmap2_policies", "libidmap2_protos", "libpng", "libprotobuf-cpp-lite", "libutils", "libz", Loading Loading @@ -185,6 +187,7 @@ cc_test { static_libs: [ "libgmock", "libidmap2_protos", "libpng", ], target: { android: { Loading Loading @@ -258,6 +261,7 @@ cc_binary { "libbase", "libcutils", "libidmap2", "libpng", "libprotobuf-cpp-lite", "libutils", "libz", Loading @@ -275,6 +279,7 @@ cc_binary { "libidmap2", "libidmap2_policies", "liblog", "libpng", "libprotobuf-cpp-lite", "libutils", "libziparchive", Loading