Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/scripts/generate-quality-report.py
Original file line number Diff line number Diff line change
Expand Up @@ -900,6 +900,9 @@ def main() -> None:
"NP_BOOLEAN_RETURN_NULL",
"RC_REF_COMPARISON_BAD_PRACTICE_BOOLEAN",
"OS_OPEN_STREAM",
"OS_OPEN_STREAM_EXCEPTION_PATH",
"OBL_UNSATISFIED_OBLIGATION_EXCEPTION_EDGE",
"RV_RETURN_VALUE_IGNORED_BAD_PRACTICE",
"REFLC_REFLECTION_MAY_INCREASE_ACCESSIBILITY_OF_CLASS",
"REC_CATCH_EXCEPTION",
"RCN_REDUNDANT_NULLCHECK_WOULD_HAVE_BEEN_A_NPE",
Expand Down
82 changes: 82 additions & 0 deletions CodenameOne/src/com/codename1/background/BackgroundTask.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
/*
* Copyright (c) 2012, Codename One and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Codename One designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Codename One through http://www.codenameone.com/ if you
* need additional information or have any questions.
*/
package com.codename1.background;

import com.codename1.ui.Display;
import java.util.Date;

/// Schedules a one-shot deferrable processing task that the operating system runs at a
/// convenient time after an earliest-begin date. On iOS this maps to a
/// `BGProcessingTaskRequest`; on Android it maps to a one-shot WorkManager request with an
/// initial delay; in the simulator it runs on a timer.
///
/// The `Runnable` passed here runs in the foreground simulator and during a live app
/// session. On iOS, after the app process has been killed, the registered task identifier
/// is relaunched by the OS and the work is reconstructed from the persisted schedule; for
/// that cold-launch path prefer `BackgroundWork` with a `BackgroundWorker` class, which is
/// reconstructed via its no-arg constructor.
///
/// #### See also
///
/// - BackgroundWork
public final class BackgroundTask {

private BackgroundTask() {
}

/// Schedules a processing task.
///
/// #### Parameters
///
/// - `id`: a stable unique id for the task; it must be declared in the build hint listing permitted background task identifiers on iOS
///
/// - `earliestBeginDate`: the earliest date at which the task may run, or null for as soon as convenient
///
/// - `requiresNetwork`: true if the task needs network connectivity
///
/// - `requiresPower`: true if the task needs the device to be charging
///
/// - `task`: the work to run
public static void scheduleProcessing(String id, Date earliestBeginDate, boolean requiresNetwork, boolean requiresPower, Runnable task) {
long earliest = earliestBeginDate == null ? 0 : earliestBeginDate.getTime();
Display.getInstance().scheduleBackgroundProcessing(id, earliest, requiresNetwork, requiresPower, task);
}

/// Cancels a previously scheduled processing task.
///
/// #### Parameters
///
/// - `id`: the task id
public static void cancel(String id) {
Display.getInstance().cancelBackgroundProcessing(id);
}

/// Returns true if the current platform supports deferrable background processing.
///
/// #### Returns
///
/// true if background processing is supported
public static boolean isSupported() {
return Display.getInstance().isBackgroundProcessingSupported();
}
}
69 changes: 69 additions & 0 deletions CodenameOne/src/com/codename1/background/BackgroundWork.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/*
* Copyright (c) 2012, Codename One and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Codename One designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Codename One through http://www.codenameone.com/ if you
* need additional information or have any questions.
*/
package com.codename1.background;

import com.codename1.ui.Display;

/// Entry point for scheduling constraint-aware background work. On Android this maps to
/// WorkManager and on iOS to `BGTaskScheduler`. In the simulator the work runs on a timer
/// and honors the constraint toggles in the Simulate menu.
///
/// #### See also
///
/// - WorkRequest
///
/// - BackgroundWorker
public final class BackgroundWork {

private BackgroundWork() {
}

/// Schedules a unit of background work. If a request with the same id was previously
/// scheduled it is replaced. On platforms that do not support background work this is
/// a no-op; check `#isSupported()` first.
///
/// #### Parameters
///
/// - `request`: the work request to schedule
public static void schedule(WorkRequest request) {
Display.getInstance().scheduleBackgroundWork(request);
}

/// Cancels previously scheduled work by id.
///
/// #### Parameters
///
/// - `workId`: the id of the work to cancel
public static void cancel(String workId) {
Display.getInstance().cancelBackgroundWork(workId);
}

/// Returns true if the current platform supports constraint-aware background work.
///
/// #### Returns
///
/// true if background work is supported
public static boolean isSupported() {
return Display.getInstance().isBackgroundWorkSupported();
}
}
58 changes: 58 additions & 0 deletions CodenameOne/src/com/codename1/background/BackgroundWorker.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/*
* Copyright (c) 2012, Codename One and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Codename One designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Codename One through http://www.codenameone.com/ if you
* need additional information or have any questions.
*/
package com.codename1.background;

import com.codename1.util.Callback;
import java.util.Map;

/// Implemented by an application class to perform constraint-aware background work
/// scheduled through `BackgroundWork#schedule(WorkRequest)`.
///
/// The implementing class MUST have a public no-argument constructor: the platform may
/// reconstruct a fresh instance after the app process has been killed and cold launched
/// to run the work, so no state from the foreground app is available. Pass any required
/// state through the work request input data.
///
/// #### See also
///
/// - BackgroundWork
///
/// - WorkRequest
public interface BackgroundWorker {

/// Performs the background work. The implementation should call `onComplete` with
/// `Boolean.TRUE` on success or `Boolean.FALSE` to request that the platform retry
/// the work later. The work must finish before `deadline`; if it does not, the
/// platform may terminate it.
///
/// #### Parameters
///
/// - `workId`: the id of the work request being executed
///
/// - `inputData`: the immutable input data supplied to the work request
///
/// - `deadline`: the time in milliseconds since the epoch by which the work must finish
///
/// - `onComplete`: callback invoked with the outcome (true for success, false to retry)
void performWork(String workId, Map<String, String> inputData, long deadline, Callback<Boolean> onComplete);
}
126 changes: 126 additions & 0 deletions CodenameOne/src/com/codename1/background/ForegroundService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
/*
* Copyright (c) 2012, Codename One and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Codename One designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Codename One through http://www.codenameone.com/ if you
* need additional information or have any questions.
*/
package com.codename1.background;

import com.codename1.ui.Display;

/// Runs a long lived task while a persistent system notification is shown to the user.
/// This is an Android foreground service. On iOS, which has no foreground service concept,
/// the task runs under a limited background execution window accompanied by a local
/// notification (best effort); check `#isSupported()` to detect full support.
///
/// Usage
/// ```java
/// ForegroundService svc = ForegroundService.start("downloads", "Downloading", "Please wait", null,
/// service -> {
/// for (int i = 0; i <= 100; i++) {
/// service.updateNotification("Downloading", i + "%");
/// // ... do a chunk of work ...
/// }
/// });
/// // the service auto-stops when the task returns, or call svc.stop() early
/// ```
public final class ForegroundService {

/// The long running task executed by a foreground service.
public interface Task {

/// Runs the work. The accompanying notification remains visible until this method
/// returns or `ForegroundService#stop()` is called.
///
/// #### Parameters
///
/// - `service`: the running service, used to update the notification or stop early
void run(ForegroundService service);
}

private Object nativeHandle;
private boolean running;

private ForegroundService() {
}

/// Starts a foreground service that shows a persistent notification and runs the task
/// on a background thread.
///
/// #### Parameters
///
/// - `channelId`: the notification channel id to post the notification on
///
/// - `title`: the notification title
///
/// - `body`: the notification body
///
/// - `iconName`: the small icon resource name, or null for the default app icon
///
/// - `task`: the work to run
///
/// #### Returns
///
/// the running service handle
public static ForegroundService start(String channelId, String title, String body, String iconName, Task task) {
ForegroundService svc = new ForegroundService();
svc.nativeHandle = Display.getInstance().startForegroundService(channelId, title, body, iconName, task, svc);
svc.running = true;
return svc;
}

/// Updates the text of the foreground service notification.
///
/// #### Parameters
///
/// - `title`: the new title
///
/// - `body`: the new body
public void updateNotification(String title, String body) {
if (running) {
Display.getInstance().updateForegroundServiceNotification(nativeHandle, title, body);
}
}

/// Stops the service and removes its notification.
public void stop() {
if (running) {
running = false;
Display.getInstance().stopForegroundService(nativeHandle);
}
}

/// Returns true if the service is currently running.
///
/// #### Returns
///
/// true if running
public boolean isRunning() {
return running;
}

/// Returns true if the current platform fully supports foreground services.
///
/// #### Returns
///
/// true if foreground services are supported
public static boolean isSupported() {
return Display.getInstance().isForegroundServiceSupported();
}
}
Loading
Loading