@Override protected void plantOneOffFlexSupport(JobRequest request, AlarmManager alarmManager, PendingIntent pendingIntent) { long currentTime = System.currentTimeMillis(); long startMs = currentTime + Common.getStartMsSupportFlex(request); long lengthMs = Common.getEndMsSupportFlex(request) - Common.getStartMsSupportFlex(request); alarmManager.setWindow(AlarmManager.RTC, startMs, lengthMs, pendingIntent); mCat.d("Scheduled repeating alarm (flex support), %s, start %s, end %s, flex %s", request, JobUtil.timeToString(Common.getStartMsSupportFlex(request)), JobUtil.timeToString(Common.getEndMsSupportFlex(request)), JobUtil.timeToString(request.getFlexMs())); } }
if (!JobUtil.hasWakeLockPermission(context)) { CAT.w("No wake lock permission"); if (!JobUtil.hasBootPermission(context)) { CAT.w("No boot permission");
/** * @param context Any context. * @return Whether the package has the WAKE_LOCK permission. */ public static boolean hasWakeLockPermission(Context context) { return hasPermission(context, Manifest.permission.WAKE_LOCK, 0); }
protected JobInfo.Builder createBaseBuilder(JobRequest request, boolean allowPersisting) { JobInfo.Builder builder = new JobInfo.Builder(request.getJobId(), new ComponentName(mContext, PlatformJobService.class)) .setRequiresCharging(request.requiresCharging()) .setRequiresDeviceIdle(request.requiresDeviceIdle()) .setRequiredNetworkType(convertNetworkType(request.requiredNetworkType())) .setPersisted(allowPersisting && !request.isTransient() && JobUtil.hasBootPermission(mContext)); return setTransientBundle(request, builder); }
static boolean acquireWakeLock(@NonNull Context context, @Nullable PowerManager.WakeLock wakeLock, long timeoutMillis) { if (wakeLock != null && !wakeLock.isHeld() && JobUtil.hasWakeLockPermission(context)) { // Even if we have the permission, some devices throw an exception in the try block nonetheless, // I'm looking at you, Samsung SM-T805 try { wakeLock.acquire(timeoutMillis); return true; } catch (Exception e) { // saw an NPE on rooted Galaxy Nexus Android 4.1.1 // android.os.IPowerManager$Stub$Proxy.acquireWakeLock(IPowerManager.java:288) CAT.e(e); } } return false; }
protected <T extends Task.Builder> T prepareBuilder(T builder, JobRequest request) { builder.setTag(createTag(request)) .setService(PlatformGcmService.class) .setUpdateCurrent(true) .setRequiredNetwork(convertNetworkType(request.requiredNetworkType())) .setPersisted(JobUtil.hasBootPermission(mContext)) .setRequiresCharging(request.requiresCharging()) .setExtras(request.getTransientExtras()); return builder; }
static boolean acquireWakeLock(@NonNull Context context, @Nullable PowerManager.WakeLock wakeLock, long timeoutMillis) { if (wakeLock != null && !wakeLock.isHeld() && JobUtil.hasWakeLockPermission(context)) { // Even if we have the permission, some devices throw an exception in the try block nonetheless, // I'm looking at you, Samsung SM-T805 try { wakeLock.acquire(timeoutMillis); return true; } catch (Exception e) { // saw an NPE on rooted Galaxy Nexus Android 4.1.1 // android.os.IPowerManager$Stub$Proxy.acquireWakeLock(IPowerManager.java:288) CAT.e(e); } } return false; }
@Override protected void plantOneOffInexact(JobRequest request, AlarmManager alarmManager, PendingIntent pendingIntent) { long currentTime = System.currentTimeMillis(); long startMs = currentTime + Common.getStartMs(request); long lengthMs = Common.getEndMs(request) - Common.getStartMs(request); alarmManager.setWindow(AlarmManager.RTC, startMs, lengthMs, pendingIntent); mCat.d("Schedule alarm, %s, start %s, end %s", request, JobUtil.timeToString(Common.getStartMs(request)), JobUtil.timeToString(Common.getEndMs(request))); }
if (!JobUtil.hasWakeLockPermission(context)) { CAT.w("No wake lock permission"); if (!JobUtil.hasBootPermission(context)) { CAT.w("No boot permission");
/** * @param context Any context. * @return Whether the package has the RECEIVE_BOOT_COMPLETED permission. */ public static boolean hasBootPermission(Context context) { return hasPermission(context, Manifest.permission.RECEIVE_BOOT_COMPLETED, 0); }
protected JobInfo.Builder createBaseBuilder(JobRequest request, boolean allowPersisting) { JobInfo.Builder builder = new JobInfo.Builder(request.getJobId(), new ComponentName(mContext, PlatformJobService.class)) .setRequiresCharging(request.requiresCharging()) .setRequiresDeviceIdle(request.requiresDeviceIdle()) .setRequiredNetworkType(convertNetworkType(request.requiredNetworkType())) .setPersisted(allowPersisting && !request.isTransient() && JobUtil.hasBootPermission(mContext)); return setTransientBundle(request, builder); }
@Test public void verifyTimeToStringReturnsCorrectString() throws Exception { assertThat(JobUtil.timeToString(TimeUnit.SECONDS.toMillis(10))).isEqualTo("00:00:10"); assertThat(JobUtil.timeToString(TimeUnit.MINUTES.toMillis(10))).isEqualTo("00:10:00"); assertThat(JobUtil.timeToString(TimeUnit.MINUTES.toMillis(70))).isEqualTo("01:10:00"); assertThat(JobUtil.timeToString(TimeUnit.HOURS.toMillis(26))).isEqualTo("02:00:00 (+1 day)"); assertThat(JobUtil.timeToString(TimeUnit.DAYS.toMillis(26))).isEqualTo("00:00:00 (+26 days)"); } }
private static boolean hasPermission(Context context, String permission, int repeatCount) { try { return PackageManager.PERMISSION_GRANTED == context.getPackageManager() .checkPermission(permission, context.getPackageName()); } catch (Exception e) { CAT.e(e); // crash https://gist.github.com/vRallev/6affe17c93e993681bfd // give it another chance with the application context return repeatCount < 1 && hasPermission(context.getApplicationContext(), permission, repeatCount + 1); } } }
protected <T extends Task.Builder> T prepareBuilder(T builder, JobRequest request) { builder.setTag(createTag(request)) .setService(PlatformGcmService.class) .setUpdateCurrent(true) .setRequiredNetwork(convertNetworkType(request.requiredNetworkType())) .setPersisted(JobUtil.hasBootPermission(mContext)) .setRequiresCharging(request.requiresCharging()) .setExtras(request.getTransientExtras()); return builder; }
protected void plantOneOffFlexSupport(JobRequest request, AlarmManager alarmManager, PendingIntent pendingIntent) { long triggerAtMs = JobConfig.getClock().currentTimeMillis() + Common.getAverageDelayMsSupportFlex(request); alarmManager.set(AlarmManager.RTC, triggerAtMs, pendingIntent); mCat.d("Scheduled repeating alarm (flex support), %s, interval %s, flex %s", request, JobUtil.timeToString(request.getIntervalMs()), JobUtil.timeToString(request.getFlexMs())); }
/** * @param context Any context. * @return Whether the package has the WAKE_LOCK permission. */ public static boolean hasWakeLockPermission(Context context) { return hasPermission(context, Manifest.permission.WAKE_LOCK, 0); }
private void logScheduled(JobRequest request) { mCat.d("Scheduled alarm, %s, delay %s (from now), exact %b, reschedule count %d", request, JobUtil.timeToString(Common.getAverageDelayMs(request)), request.isExact(), Common.getRescheduleCount(request)); }
/** * @param context Any context. * @return Whether the package has the RECEIVE_BOOT_COMPLETED permission. */ public static boolean hasBootPermission(Context context) { return hasPermission(context, Manifest.permission.RECEIVE_BOOT_COMPLETED, 0); }
@Override public void plantPeriodicFlexSupport(JobRequest request) { long startMs = Common.getStartMsSupportFlex(request); long endMs = Common.getEndMsSupportFlex(request); JobInfo jobInfo = createBuilderOneOff(createBaseBuilder(request, true), startMs, endMs).build(); int scheduleResult = schedule(jobInfo); if (scheduleResult == ERROR_BOOT_PERMISSION) { jobInfo = createBuilderOneOff(createBaseBuilder(request, false), startMs, endMs).build(); scheduleResult = schedule(jobInfo); } mCat.d("Schedule periodic (flex support) jobInfo %s, %s, start %s, end %s, flex %s", scheduleResultToString(scheduleResult), request, JobUtil.timeToString(startMs), JobUtil.timeToString(endMs), JobUtil.timeToString(request.getFlexMs())); }
private static boolean hasPermission(Context context, String permission, int repeatCount) { try { return PackageManager.PERMISSION_GRANTED == context.getPackageManager() .checkPermission(permission, context.getPackageName()); } catch (Exception e) { CAT.e(e); // crash https://gist.github.com/vRallev/6affe17c93e993681bfd // give it another chance with the application context return repeatCount < 1 && hasPermission(context.getApplicationContext(), permission, repeatCount + 1); } } }