Loading services/core/java/com/android/server/content/ContentService.java +6 −2 Original line number Diff line number Diff line Loading @@ -646,6 +646,7 @@ public final class ContentService extends IContentService.Stub { SyncManager syncManager = getSyncManager(); if (syncManager == null) return; int userId = UserHandle.getCallingUserId(); final int callingUid = Binder.getCallingUid(); long identityToken = clearCallingIdentity(); try { Loading @@ -658,7 +659,8 @@ public final class ContentService extends IContentService.Stub { // Remove periodic sync. mContext.enforceCallingOrSelfPermission(Manifest.permission.WRITE_SYNC_SETTINGS, "no permission to write the sync settings"); getSyncManager().removePeriodicSync(info, extras); getSyncManager().removePeriodicSync(info, extras, "cancelRequest() by uid=" + callingUid); } // Cancel active syncs and clear pending syncs from the queue. syncManager.cancelScheduledSyncOperation(info, extras); Loading Loading @@ -814,13 +816,15 @@ public final class ContentService extends IContentService.Stub { mContext.enforceCallingOrSelfPermission(Manifest.permission.WRITE_SYNC_SETTINGS, "no permission to write the sync settings"); final int callingUid = Binder.getCallingUid(); int userId = UserHandle.getCallingUserId(); long identityToken = clearCallingIdentity(); try { getSyncManager() .removePeriodicSync( new SyncStorageEngine.EndPoint(account, authority, userId), extras); extras, "removePeriodicSync() by uid=" + callingUid); } finally { restoreCallingIdentity(identityToken); } Loading services/core/java/com/android/server/content/SyncManager.java +83 −27 Original line number Diff line number Diff line Loading @@ -59,6 +59,7 @@ import android.net.NetworkInfo; import android.net.TrafficStats; import android.os.BatteryStats; import android.os.Binder; import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.os.IBinder; Loading Loading @@ -141,6 +142,8 @@ public class SyncManager { private static final boolean DEBUG_ACCOUNT_ACCESS = false; private static final boolean ENABLE_SUSPICIOUS_CHECK = Build.IS_DEBUGGABLE; /** Delay a sync due to local changes this long. In milliseconds */ private static final long LOCAL_SYNC_DELAY; Loading Loading @@ -463,7 +466,7 @@ public class SyncManager { } if (opx.key.equals(opy.key)) { mLogger.log("Removing duplicate sync: ", opy); mJobScheduler.cancel(opy.jobId); cancelJob(opy, "cleanupJobs() x=" + opx + " y=" + opy); } } } Loading Loading @@ -501,15 +504,21 @@ public class SyncManager { } } } if (mLogger.enabled()) { mLogger.log("Connected to JobScheduler: " + numPersistedPeriodicSyncs + " periodic syncs " + numPersistedOneshotSyncs + " oneshot syncs."); } final int totalJobs = (mJobSchedulerInternal == null) ? -1 : mJobSchedulerInternal.countJobs(); final String summary = "Loaded persisted syncs: " + numPersistedPeriodicSyncs + " periodic syncs, " + numPersistedOneshotSyncs + " oneshot syncs, " + (pendingJobs.size()) + " total system server jobs, " + totalJobs + " total jobs."; Slog.i(TAG, summary); mLogger.log(summary); cleanupJobs(); if ((numPersistedPeriodicSyncs == 0) && likelyHasPeriodicSyncs()) { Slog.wtf(TAG, "Device booted with no persisted periodic syncs."); if (ENABLE_SUSPICIOUS_CHECK && (numPersistedPeriodicSyncs == 0) && likelyHasPeriodicSyncs()) { Slog.wtf(TAG, "Device booted with no persisted periodic syncs: " + summary); } } finally { Binder.restoreCallingIdentity(token); Loading @@ -520,6 +529,7 @@ public class SyncManager { * @return whether the device most likely has some periodic syncs. */ private boolean likelyHasPeriodicSyncs() { // STOPSHIP Remove the google specific string. try { return AccountManager.get(mContext).getAccountsByType("com.google").length > 0; } catch (Throwable th) { Loading Loading @@ -566,7 +576,7 @@ public class SyncManager { mSyncStorageEngine.setOnAuthorityRemovedListener(new SyncStorageEngine.OnAuthorityRemovedListener() { @Override public void onAuthorityRemoved(EndPoint removedAuthority) { removeSyncsForAuthority(removedAuthority); removeSyncsForAuthority(removedAuthority, "onAuthorityRemoved"); } }); Loading Loading @@ -1118,14 +1128,14 @@ public class SyncManager { } } private void removeSyncsForAuthority(EndPoint info) { private void removeSyncsForAuthority(EndPoint info, String why) { mLogger.log("removeSyncsForAuthority: ", info); verifyJobScheduler(); List<SyncOperation> ops = getAllPendingSyncs(); for (SyncOperation op: ops) { if (op.target.matchesSpec(info)) { mLogger.log("canceling: ", op); getJobScheduler().cancel(op.jobId); cancelJob(op, why); } } } Loading @@ -1133,8 +1143,9 @@ public class SyncManager { /** * Remove a specific periodic sync identified by its target and extras. */ public void removePeriodicSync(EndPoint target, Bundle extras) { Message m = mSyncHandler.obtainMessage(mSyncHandler.MESSAGE_REMOVE_PERIODIC_SYNC, target); public void removePeriodicSync(EndPoint target, Bundle extras, String why) { Message m = mSyncHandler.obtainMessage(mSyncHandler.MESSAGE_REMOVE_PERIODIC_SYNC, Pair.create(target, why)); m.setData(extras); m.sendToTarget(); } Loading Loading @@ -1359,7 +1370,7 @@ public class SyncManager { for (SyncOperation op: ops) { if (!op.isPeriodic && op.target.matchesSpec(target)) { count++; getJobScheduler().cancel(op.jobId); cancelJob(op, why); postScheduleSyncMessage(op, 0 /* min delay */); } } Loading Loading @@ -1484,7 +1495,7 @@ public class SyncManager { if (isLoggable) { Slog.v(TAG, "Cancelling duplicate sync " + op); } getJobScheduler().cancel(op.jobId); cancelJob(op, "scheduleSyncOperationH-duplicate"); } } } Loading Loading @@ -1544,7 +1555,7 @@ public class SyncManager { List<SyncOperation> ops = getAllPendingSyncs(); for (SyncOperation op: ops) { if (!op.isPeriodic && op.target.matchesSpec(info)) { getJobScheduler().cancel(op.jobId); cancelJob(op, "clearScheduledSyncOperations"); getSyncStorageEngine().markPending(op.target, false); } } Loading @@ -1562,7 +1573,7 @@ public class SyncManager { for (SyncOperation op: ops) { if (!op.isPeriodic && op.target.matchesSpec(info) && syncExtrasEquals(extras, op.extras, false)) { getJobScheduler().cancel(op.jobId); cancelJob(op, "cancelScheduledSyncOperation"); } } setAuthorityPendingState(info); Loading Loading @@ -1678,7 +1689,7 @@ public class SyncManager { List<SyncOperation> ops = getAllPendingSyncs(); for (SyncOperation op: ops) { if (op.target.userId == userId) { getJobScheduler().cancel(op.jobId); cancelJob(op, "user removed u" + userId); } } } Loading Loading @@ -2710,7 +2721,8 @@ public class SyncManager { data.flex, data.extras); break; case MESSAGE_REMOVE_PERIODIC_SYNC: removePeriodicSyncH((EndPoint)msg.obj, msg.getData()); Pair<EndPoint, String> args = (Pair<EndPoint, String>) (msg.obj); removePeriodicSyncH(args.first, msg.getData(), args.second); break; case SyncHandler.MESSAGE_CANCEL: Loading Loading @@ -2848,7 +2860,7 @@ public class SyncManager { // mSyncJobService.callJobFinished is async, so cancel the job to ensure we don't // find the this job in the pending jobs list while looking for duplicates // before scheduling it at a later time. getJobScheduler().cancel(op.jobId); cancelJob(op, "deferSyncH()"); scheduleSyncOperationH(op, delay); } } Loading Loading @@ -2998,7 +3010,7 @@ public class SyncManager { for (SyncOperation op: ops) { if (!containsAccountAndUser(allAccounts, op.target.account, op.target.userId)) { mLogger.log("canceling: ", op); getJobScheduler().cancel(op.jobId); cancelJob(op, "updateRunningAccountsH()"); } } Loading Loading @@ -3105,7 +3117,7 @@ public class SyncManager { /** * Remove this periodic sync operation and all one-off operations initiated by it. */ private void removePeriodicSyncInternalH(SyncOperation syncOperation) { private void removePeriodicSyncInternalH(SyncOperation syncOperation, String why) { // Remove this periodic sync and all one-off syncs initiated by it. List<SyncOperation> ops = getAllPendingSyncs(); for (SyncOperation op: ops) { Loading @@ -3117,18 +3129,18 @@ public class SyncManager { runSyncFinishedOrCanceledH(null, asc); } mLogger.log("removePeriodicSyncInternalH-canceling: ", op); getJobScheduler().cancel(op.jobId); cancelJob(op, why); } } } private void removePeriodicSyncH(EndPoint target, Bundle extras) { private void removePeriodicSyncH(EndPoint target, Bundle extras, String why) { verifyJobScheduler(); List<SyncOperation> ops = getAllPendingSyncs(); for (SyncOperation op: ops) { if (op.isPeriodic && op.target.matchesSpec(target) && syncExtrasEquals(op.extras, extras, true /* includeSyncSettings */)) { removePeriodicSyncInternalH(op); removePeriodicSyncInternalH(op, why); } } } Loading Loading @@ -3369,7 +3381,7 @@ public class SyncManager { // Note this part is probably okay to do before closeActiveSyncContext()... // But moved here to restore OC-dev's behavior. See b/64597061. if (!syncOperation.isPeriodic) { getJobScheduler().cancel(syncOperation.jobId); cancelJob(syncOperation, "runSyncFinishedOrCanceledH()-finished"); } if (!syncResult.hasError()) { Loading Loading @@ -3410,7 +3422,7 @@ public class SyncManager { } if (!syncOperation.isPeriodic) { getJobScheduler().cancel(syncOperation.jobId); cancelJob(syncOperation, "runSyncFinishedOrCanceledH()-canceled"); } if (activeSyncContext.mSyncAdapter != null) { Loading Loading @@ -3747,4 +3759,48 @@ public class SyncManager { return mContext; } } private void cancelJob(SyncOperation op, String why) { if (op == null) { Slog.wtf(TAG, "Null sync operation detected."); return; } if (op.isPeriodic) { mLogger.log("Removing periodic sync ", op, " for ", why); if (ENABLE_SUSPICIOUS_CHECK && isSuspiciousPeriodicSyncRemoval(op)) { wtfWithLog("Suspicious removal of " + op + " for " + why); } } getJobScheduler().cancel(op.jobId); } private boolean isSuspiciousPeriodicSyncRemoval(SyncOperation op) { // STOPSHIP Remove the google specific string. if (!op.isPeriodic){ return false; } switch (op.target.provider) { case "gmail-ls": case "com.android.contacts.metadata": break; default: return false; } final Account account = op.target.account; final Account[] accounts = AccountManager.get(mContext) .getAccountsByTypeAsUser(account.type, UserHandle.of(op.target.userId)); for (Account a : accounts) { if (a.equals(account)) { return true; // Account still exists. Suspicious! } } // Account no longer exists. Makes sense... return false; } private void wtfWithLog(String message) { Slog.wtf(TAG, message); mLogger.log("WTF: ", message); } } services/core/java/com/android/server/job/JobSchedulerInternal.java +5 −0 Original line number Diff line number Diff line Loading @@ -37,4 +37,9 @@ public interface JobSchedulerInternal { void addBackingUpUid(int uid); void removeBackingUpUid(int uid); void clearAllBackingUpUids(); /** * @return the total number of jobs across all UIDs. */ int countJobs(); } services/core/java/com/android/server/job/JobSchedulerService.java +13 −0 Original line number Diff line number Diff line Loading @@ -1835,6 +1835,13 @@ public final class JobSchedulerService extends com.android.server.SystemService } } } @Override public int countJobs() { synchronized (mLock) { return mJobs.size(); } } } /** Loading Loading @@ -2015,6 +2022,12 @@ public final class JobSchedulerService extends com.android.server.SystemService @Override public void cancelAll() throws RemoteException { final int uid = Binder.getCallingUid(); switch (uid) { case Process.SYSTEM_UID: // This really shouldn't happen. Slog.wtf(TAG, "JobScheduler.cancelAll() called for uid=" + uid); return; } long ident = Binder.clearCallingIdentity(); try { Loading services/core/java/com/android/server/job/JobStore.java +5 −8 Original line number Diff line number Diff line Loading @@ -544,6 +544,7 @@ public final class JobStore { @Override public void run() { int numJobs = 0; try { List<JobStatus> jobs; FileInputStream fis = mJobsFile.openRead(); Loading @@ -557,6 +558,7 @@ public final class JobStore { js.prepareLocked(am); js.enqueueTime = now; this.jobSet.add(js); numJobs++; } } } Loading @@ -565,15 +567,10 @@ public final class JobStore { if (DEBUG) { Slog.d(TAG, "Could not find jobs file, probably there was nothing to load."); } } catch (XmlPullParserException e) { if (DEBUG) { Slog.d(TAG, "Error parsing xml.", e); } } catch (IOException e) { if (DEBUG) { Slog.d(TAG, "Error parsing xml.", e); } } catch (XmlPullParserException | IOException e) { Slog.wtf(TAG, "Error jobstore xml.", e); } Slog.i(TAG, "Read " + numJobs + " jobs"); } private List<JobStatus> readJobMapImpl(FileInputStream fis, boolean rtcIsGood) Loading Loading
services/core/java/com/android/server/content/ContentService.java +6 −2 Original line number Diff line number Diff line Loading @@ -646,6 +646,7 @@ public final class ContentService extends IContentService.Stub { SyncManager syncManager = getSyncManager(); if (syncManager == null) return; int userId = UserHandle.getCallingUserId(); final int callingUid = Binder.getCallingUid(); long identityToken = clearCallingIdentity(); try { Loading @@ -658,7 +659,8 @@ public final class ContentService extends IContentService.Stub { // Remove periodic sync. mContext.enforceCallingOrSelfPermission(Manifest.permission.WRITE_SYNC_SETTINGS, "no permission to write the sync settings"); getSyncManager().removePeriodicSync(info, extras); getSyncManager().removePeriodicSync(info, extras, "cancelRequest() by uid=" + callingUid); } // Cancel active syncs and clear pending syncs from the queue. syncManager.cancelScheduledSyncOperation(info, extras); Loading Loading @@ -814,13 +816,15 @@ public final class ContentService extends IContentService.Stub { mContext.enforceCallingOrSelfPermission(Manifest.permission.WRITE_SYNC_SETTINGS, "no permission to write the sync settings"); final int callingUid = Binder.getCallingUid(); int userId = UserHandle.getCallingUserId(); long identityToken = clearCallingIdentity(); try { getSyncManager() .removePeriodicSync( new SyncStorageEngine.EndPoint(account, authority, userId), extras); extras, "removePeriodicSync() by uid=" + callingUid); } finally { restoreCallingIdentity(identityToken); } Loading
services/core/java/com/android/server/content/SyncManager.java +83 −27 Original line number Diff line number Diff line Loading @@ -59,6 +59,7 @@ import android.net.NetworkInfo; import android.net.TrafficStats; import android.os.BatteryStats; import android.os.Binder; import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.os.IBinder; Loading Loading @@ -141,6 +142,8 @@ public class SyncManager { private static final boolean DEBUG_ACCOUNT_ACCESS = false; private static final boolean ENABLE_SUSPICIOUS_CHECK = Build.IS_DEBUGGABLE; /** Delay a sync due to local changes this long. In milliseconds */ private static final long LOCAL_SYNC_DELAY; Loading Loading @@ -463,7 +466,7 @@ public class SyncManager { } if (opx.key.equals(opy.key)) { mLogger.log("Removing duplicate sync: ", opy); mJobScheduler.cancel(opy.jobId); cancelJob(opy, "cleanupJobs() x=" + opx + " y=" + opy); } } } Loading Loading @@ -501,15 +504,21 @@ public class SyncManager { } } } if (mLogger.enabled()) { mLogger.log("Connected to JobScheduler: " + numPersistedPeriodicSyncs + " periodic syncs " + numPersistedOneshotSyncs + " oneshot syncs."); } final int totalJobs = (mJobSchedulerInternal == null) ? -1 : mJobSchedulerInternal.countJobs(); final String summary = "Loaded persisted syncs: " + numPersistedPeriodicSyncs + " periodic syncs, " + numPersistedOneshotSyncs + " oneshot syncs, " + (pendingJobs.size()) + " total system server jobs, " + totalJobs + " total jobs."; Slog.i(TAG, summary); mLogger.log(summary); cleanupJobs(); if ((numPersistedPeriodicSyncs == 0) && likelyHasPeriodicSyncs()) { Slog.wtf(TAG, "Device booted with no persisted periodic syncs."); if (ENABLE_SUSPICIOUS_CHECK && (numPersistedPeriodicSyncs == 0) && likelyHasPeriodicSyncs()) { Slog.wtf(TAG, "Device booted with no persisted periodic syncs: " + summary); } } finally { Binder.restoreCallingIdentity(token); Loading @@ -520,6 +529,7 @@ public class SyncManager { * @return whether the device most likely has some periodic syncs. */ private boolean likelyHasPeriodicSyncs() { // STOPSHIP Remove the google specific string. try { return AccountManager.get(mContext).getAccountsByType("com.google").length > 0; } catch (Throwable th) { Loading Loading @@ -566,7 +576,7 @@ public class SyncManager { mSyncStorageEngine.setOnAuthorityRemovedListener(new SyncStorageEngine.OnAuthorityRemovedListener() { @Override public void onAuthorityRemoved(EndPoint removedAuthority) { removeSyncsForAuthority(removedAuthority); removeSyncsForAuthority(removedAuthority, "onAuthorityRemoved"); } }); Loading Loading @@ -1118,14 +1128,14 @@ public class SyncManager { } } private void removeSyncsForAuthority(EndPoint info) { private void removeSyncsForAuthority(EndPoint info, String why) { mLogger.log("removeSyncsForAuthority: ", info); verifyJobScheduler(); List<SyncOperation> ops = getAllPendingSyncs(); for (SyncOperation op: ops) { if (op.target.matchesSpec(info)) { mLogger.log("canceling: ", op); getJobScheduler().cancel(op.jobId); cancelJob(op, why); } } } Loading @@ -1133,8 +1143,9 @@ public class SyncManager { /** * Remove a specific periodic sync identified by its target and extras. */ public void removePeriodicSync(EndPoint target, Bundle extras) { Message m = mSyncHandler.obtainMessage(mSyncHandler.MESSAGE_REMOVE_PERIODIC_SYNC, target); public void removePeriodicSync(EndPoint target, Bundle extras, String why) { Message m = mSyncHandler.obtainMessage(mSyncHandler.MESSAGE_REMOVE_PERIODIC_SYNC, Pair.create(target, why)); m.setData(extras); m.sendToTarget(); } Loading Loading @@ -1359,7 +1370,7 @@ public class SyncManager { for (SyncOperation op: ops) { if (!op.isPeriodic && op.target.matchesSpec(target)) { count++; getJobScheduler().cancel(op.jobId); cancelJob(op, why); postScheduleSyncMessage(op, 0 /* min delay */); } } Loading Loading @@ -1484,7 +1495,7 @@ public class SyncManager { if (isLoggable) { Slog.v(TAG, "Cancelling duplicate sync " + op); } getJobScheduler().cancel(op.jobId); cancelJob(op, "scheduleSyncOperationH-duplicate"); } } } Loading Loading @@ -1544,7 +1555,7 @@ public class SyncManager { List<SyncOperation> ops = getAllPendingSyncs(); for (SyncOperation op: ops) { if (!op.isPeriodic && op.target.matchesSpec(info)) { getJobScheduler().cancel(op.jobId); cancelJob(op, "clearScheduledSyncOperations"); getSyncStorageEngine().markPending(op.target, false); } } Loading @@ -1562,7 +1573,7 @@ public class SyncManager { for (SyncOperation op: ops) { if (!op.isPeriodic && op.target.matchesSpec(info) && syncExtrasEquals(extras, op.extras, false)) { getJobScheduler().cancel(op.jobId); cancelJob(op, "cancelScheduledSyncOperation"); } } setAuthorityPendingState(info); Loading Loading @@ -1678,7 +1689,7 @@ public class SyncManager { List<SyncOperation> ops = getAllPendingSyncs(); for (SyncOperation op: ops) { if (op.target.userId == userId) { getJobScheduler().cancel(op.jobId); cancelJob(op, "user removed u" + userId); } } } Loading Loading @@ -2710,7 +2721,8 @@ public class SyncManager { data.flex, data.extras); break; case MESSAGE_REMOVE_PERIODIC_SYNC: removePeriodicSyncH((EndPoint)msg.obj, msg.getData()); Pair<EndPoint, String> args = (Pair<EndPoint, String>) (msg.obj); removePeriodicSyncH(args.first, msg.getData(), args.second); break; case SyncHandler.MESSAGE_CANCEL: Loading Loading @@ -2848,7 +2860,7 @@ public class SyncManager { // mSyncJobService.callJobFinished is async, so cancel the job to ensure we don't // find the this job in the pending jobs list while looking for duplicates // before scheduling it at a later time. getJobScheduler().cancel(op.jobId); cancelJob(op, "deferSyncH()"); scheduleSyncOperationH(op, delay); } } Loading Loading @@ -2998,7 +3010,7 @@ public class SyncManager { for (SyncOperation op: ops) { if (!containsAccountAndUser(allAccounts, op.target.account, op.target.userId)) { mLogger.log("canceling: ", op); getJobScheduler().cancel(op.jobId); cancelJob(op, "updateRunningAccountsH()"); } } Loading Loading @@ -3105,7 +3117,7 @@ public class SyncManager { /** * Remove this periodic sync operation and all one-off operations initiated by it. */ private void removePeriodicSyncInternalH(SyncOperation syncOperation) { private void removePeriodicSyncInternalH(SyncOperation syncOperation, String why) { // Remove this periodic sync and all one-off syncs initiated by it. List<SyncOperation> ops = getAllPendingSyncs(); for (SyncOperation op: ops) { Loading @@ -3117,18 +3129,18 @@ public class SyncManager { runSyncFinishedOrCanceledH(null, asc); } mLogger.log("removePeriodicSyncInternalH-canceling: ", op); getJobScheduler().cancel(op.jobId); cancelJob(op, why); } } } private void removePeriodicSyncH(EndPoint target, Bundle extras) { private void removePeriodicSyncH(EndPoint target, Bundle extras, String why) { verifyJobScheduler(); List<SyncOperation> ops = getAllPendingSyncs(); for (SyncOperation op: ops) { if (op.isPeriodic && op.target.matchesSpec(target) && syncExtrasEquals(op.extras, extras, true /* includeSyncSettings */)) { removePeriodicSyncInternalH(op); removePeriodicSyncInternalH(op, why); } } } Loading Loading @@ -3369,7 +3381,7 @@ public class SyncManager { // Note this part is probably okay to do before closeActiveSyncContext()... // But moved here to restore OC-dev's behavior. See b/64597061. if (!syncOperation.isPeriodic) { getJobScheduler().cancel(syncOperation.jobId); cancelJob(syncOperation, "runSyncFinishedOrCanceledH()-finished"); } if (!syncResult.hasError()) { Loading Loading @@ -3410,7 +3422,7 @@ public class SyncManager { } if (!syncOperation.isPeriodic) { getJobScheduler().cancel(syncOperation.jobId); cancelJob(syncOperation, "runSyncFinishedOrCanceledH()-canceled"); } if (activeSyncContext.mSyncAdapter != null) { Loading Loading @@ -3747,4 +3759,48 @@ public class SyncManager { return mContext; } } private void cancelJob(SyncOperation op, String why) { if (op == null) { Slog.wtf(TAG, "Null sync operation detected."); return; } if (op.isPeriodic) { mLogger.log("Removing periodic sync ", op, " for ", why); if (ENABLE_SUSPICIOUS_CHECK && isSuspiciousPeriodicSyncRemoval(op)) { wtfWithLog("Suspicious removal of " + op + " for " + why); } } getJobScheduler().cancel(op.jobId); } private boolean isSuspiciousPeriodicSyncRemoval(SyncOperation op) { // STOPSHIP Remove the google specific string. if (!op.isPeriodic){ return false; } switch (op.target.provider) { case "gmail-ls": case "com.android.contacts.metadata": break; default: return false; } final Account account = op.target.account; final Account[] accounts = AccountManager.get(mContext) .getAccountsByTypeAsUser(account.type, UserHandle.of(op.target.userId)); for (Account a : accounts) { if (a.equals(account)) { return true; // Account still exists. Suspicious! } } // Account no longer exists. Makes sense... return false; } private void wtfWithLog(String message) { Slog.wtf(TAG, message); mLogger.log("WTF: ", message); } }
services/core/java/com/android/server/job/JobSchedulerInternal.java +5 −0 Original line number Diff line number Diff line Loading @@ -37,4 +37,9 @@ public interface JobSchedulerInternal { void addBackingUpUid(int uid); void removeBackingUpUid(int uid); void clearAllBackingUpUids(); /** * @return the total number of jobs across all UIDs. */ int countJobs(); }
services/core/java/com/android/server/job/JobSchedulerService.java +13 −0 Original line number Diff line number Diff line Loading @@ -1835,6 +1835,13 @@ public final class JobSchedulerService extends com.android.server.SystemService } } } @Override public int countJobs() { synchronized (mLock) { return mJobs.size(); } } } /** Loading Loading @@ -2015,6 +2022,12 @@ public final class JobSchedulerService extends com.android.server.SystemService @Override public void cancelAll() throws RemoteException { final int uid = Binder.getCallingUid(); switch (uid) { case Process.SYSTEM_UID: // This really shouldn't happen. Slog.wtf(TAG, "JobScheduler.cancelAll() called for uid=" + uid); return; } long ident = Binder.clearCallingIdentity(); try { Loading
services/core/java/com/android/server/job/JobStore.java +5 −8 Original line number Diff line number Diff line Loading @@ -544,6 +544,7 @@ public final class JobStore { @Override public void run() { int numJobs = 0; try { List<JobStatus> jobs; FileInputStream fis = mJobsFile.openRead(); Loading @@ -557,6 +558,7 @@ public final class JobStore { js.prepareLocked(am); js.enqueueTime = now; this.jobSet.add(js); numJobs++; } } } Loading @@ -565,15 +567,10 @@ public final class JobStore { if (DEBUG) { Slog.d(TAG, "Could not find jobs file, probably there was nothing to load."); } } catch (XmlPullParserException e) { if (DEBUG) { Slog.d(TAG, "Error parsing xml.", e); } } catch (IOException e) { if (DEBUG) { Slog.d(TAG, "Error parsing xml.", e); } } catch (XmlPullParserException | IOException e) { Slog.wtf(TAG, "Error jobstore xml.", e); } Slog.i(TAG, "Read " + numJobs + " jobs"); } private List<JobStatus> readJobMapImpl(FileInputStream fis, boolean rtcIsGood) Loading