// Copyright 2016 Google, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
////////////////////////////////////////////////////////////////////////////////
package com.firebase.jobdispatcher;
import android.support.annotation.IntDef;
import android.support.annotation.NonNull;
import com.firebase.jobdispatcher.RetryStrategy.RetryPolicy;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/**
* The FirebaseJobDispatcher provides a driver-agnostic API for scheduling and cancelling Jobs.
*
* @see #FirebaseJobDispatcher(Driver)
* @see Driver
* @see JobParameters
*/
public final class FirebaseJobDispatcher {
/**
* Indicates the schedule request seems to have been successful.
*/
public final static int SCHEDULE_RESULT_SUCCESS = 0;
/**
* Indicates the schedule request encountered an unknown error.
*/
public final static int SCHEDULE_RESULT_UNKNOWN_ERROR = 1;
/**
* Indicates the schedule request failed because the driver was unavailable.
*/
public final static int SCHEDULE_RESULT_NO_DRIVER_AVAILABLE = 2;
/**
* Indicates the schedule request failed because the Trigger was unsupported.
*/
public final static int SCHEDULE_RESULT_UNSUPPORTED_TRIGGER = 3;
/**
* Indicates the schedule request failed because the service is not exposed or configured
* correctly.
*/
public final static int SCHEDULE_RESULT_BAD_SERVICE = 4;
/**
* Indicates the cancel request seems to have been successful.
*/
public final static int CANCEL_RESULT_SUCCESS = 0;
/**
* Indicates the cancel request encountered an unknown error.
*/
public final static int CANCEL_RESULT_UNKNOWN_ERROR = 1;
/**
* Indicates the cancel request failed because the driver was unavailable.
*/
public final static int CANCEL_RESULT_NO_DRIVER_AVAILABLE = 2;
/**
* The backing Driver for this instance.
*/
private final Driver mDriver;
/**
* The ValidationEnforcer configured for the current Driver.
*/
private final ValidationEnforcer mValidator;
/**
* Single instance of a RetryStrategy.Builder, configured with the current driver's validation
* settings. We can do this because the RetryStrategy.Builder is stateless.
*/
private RetryStrategy.Builder mRetryStrategyBuilder;
/**
* Instantiates a new FirebaseJobDispatcher using the provided Driver.
*/
public FirebaseJobDispatcher(Driver driver) {
mDriver = driver;
mValidator = new ValidationEnforcer(mDriver.getValidator());
mRetryStrategyBuilder = new RetryStrategy.Builder(mValidator);
}
/**
* Attempts to schedule the provided Job.
* <p/>
* Returns one of the SCHEDULE_RESULT_ constants.
*/
@ScheduleResult
public int schedule(@NonNull Job job) {
if (!mDriver.isAvailable()) {
return SCHEDULE_RESULT_NO_DRIVER_AVAILABLE;
}
return mDriver.schedule(job);
}
/**
* Attempts to cancel the Job that matches the provided tag and endpoint.
* <p/>
* Returns one of the CANCEL_RESULT_ constants.
*/
@CancelResult
public int cancel(@NonNull String tag) {
if (!mDriver.isAvailable()) {
return CANCEL_RESULT_NO_DRIVER_AVAILABLE;
}
return mDriver.cancel(tag);
}
/**
* Attempts to cancel all Jobs registered for this package.
* <p/>
* Returns one of the CANCEL_RESULT_ constants.
*/
@CancelResult
public int cancelAll() {
if (!mDriver.isAvailable()) {
return CANCEL_RESULT_NO_DRIVER_AVAILABLE;
}
return mDriver.cancelAll();
}
/**
* Attempts to schedule the provided Job, throwing an exception if it fails.
*
* @throws ScheduleFailedException
*/
public void mustSchedule(Job job) {
if (schedule(job) != SCHEDULE_RESULT_SUCCESS) {
throw new ScheduleFailedException();
}
}
/**
* Returns a ValidationEnforcer configured for the current Driver.
*/
public ValidationEnforcer getValidator() {
return mValidator;
}
/**
* Creates a new Job.Builder, configured with the current driver's validation settings.
*/
@NonNull
public Job.Builder newJobBuilder() {
return new Job.Builder(mValidator);
}
/**
* Creates a new RetryStrategy from the provided parameters, validated with the current driver's
* {@link JobValidator}.
*
* @param policy the backoff policy to use. One of the {@link RetryPolicy} constants.
* @param initialBackoff the initial backoff, in seconds.
* @param maximumBackoff the maximum backoff, in seconds.
* @throws ValidationEnforcer.ValidationException
* @see RetryStrategy
*/
public RetryStrategy newRetryStrategy(@RetryPolicy int policy, int initialBackoff,
int maximumBackoff) {
return mRetryStrategyBuilder.build(policy, initialBackoff, maximumBackoff);
}
/**
* Results that can legally be returned from {@link #schedule(Job)} calls.
*/
@IntDef({
SCHEDULE_RESULT_SUCCESS,
SCHEDULE_RESULT_UNKNOWN_ERROR,
SCHEDULE_RESULT_NO_DRIVER_AVAILABLE,
SCHEDULE_RESULT_UNSUPPORTED_TRIGGER,
SCHEDULE_RESULT_BAD_SERVICE,
})
@Retention(RetentionPolicy.SOURCE)
public @interface ScheduleResult {
}
/**
* Results that can legally be returned from {@link #cancel(String)} or {@link #cancelAll()}
* calls.
*/
@IntDef({
CANCEL_RESULT_SUCCESS,
CANCEL_RESULT_UNKNOWN_ERROR,
CANCEL_RESULT_NO_DRIVER_AVAILABLE,
})
@Retention(RetentionPolicy.SOURCE)
public @interface CancelResult {
}
/**
* Thrown when a {@link FirebaseJobDispatcher#schedule(com.firebase.jobdispatcher.Job)} call
* fails.
*/
public final static class ScheduleFailedException extends RuntimeException {
}
}