Petri Hintukainen pushed to branch master at VideoLAN / libbluray


Commits:
ef4a9b88 by spotter at 2026-01-16T17:18:35+00:00
BD-J: Implement TVTimer and TVTimerSpec

- - - - -


4 changed files:

- src/libbluray/bdj/java/javax/tv/util/TVTimer.java
- + src/libbluray/bdj/java/javax/tv/util/TVTimerImpl.java
- src/libbluray/bdj/java/javax/tv/util/TVTimerSpec.java
- src/libbluray/bdj/java/org/videolan/BDJXletContext.java


Changes:

=====================================
src/libbluray/bdj/java/javax/tv/util/TVTimer.java
=====================================
@@ -20,11 +20,23 @@
 package javax.tv.util;
 
 import org.videolan.Logger;
+import org.videolan.BDJXletContext;
 
 public abstract class TVTimer
 {
-    public static TVTimer getTimer() {
-        Logger.unimplemented(TVTimer.class.getName(), "getTimer");
+    public static synchronized TVTimer getTimer() {
+        BDJXletContext context = BDJXletContext.getCurrentContext();
+
+        if (context != null) {
+            if (context.getTVTimer() == null) {
+                context.setTVTimer(new TVTimerImpl());
+            }
+
+            return context.getTVTimer();
+        }
+
+        logger.error("getTimer(): no context at " + Logger.dumpStack());
+
         return null;
     }
 
@@ -36,4 +48,6 @@ public abstract class TVTimer
     public abstract long getMinRepeatInterval();
 
     public abstract void deschedule(TVTimerSpec paramTVTimerSpec);
+
+    private static final Logger logger = 
Logger.getLogger(TVTimer.class.getName());
 }


=====================================
src/libbluray/bdj/java/javax/tv/util/TVTimerImpl.java
=====================================
@@ -0,0 +1,110 @@
+/*
+ * This file is part of libbluray
+ * Copyright (C) 2016  VideoLAN
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see
+ * <http://www.gnu.org/licenses/>.
+ */
+
+package javax.tv.util;
+
+import java.util.Timer;
+import java.util.TimerTask;
+import java.util.Hashtable;
+
+public class TVTimerImpl extends TVTimer
+{
+    private Timer timer;
+    private Hashtable scheduledTasks = new Hashtable(); // TVTimerSpec -> 
TimerTask
+
+    public TVTimerImpl() {
+        timer = new Timer(true); // daemon thread
+    }
+
+    public TVTimerSpec scheduleTimerSpec(final TVTimerSpec spec)
+            throws TVTimerScheduleFailedException {
+        if (spec == null) {
+            throw new TVTimerScheduleFailedException("TVTimerSpec is null");
+        }
+
+        // Cancel any existing schedule for this spec
+        deschedule(spec);
+
+        final TVTimer self = this;
+        TimerTask task = new TimerTask() {
+            public void run() {
+                try {
+                    spec.notifyListeners(self);
+                } catch (Exception e) {
+                    System.err.println("TVTimer: Exception in timer callback: 
" + e);
+                    e.printStackTrace();
+                }
+                if (!spec.isRepeat()) {
+                    scheduledTasks.remove(spec);
+                }
+            }
+        };
+
+        scheduledTasks.put(spec, task);
+
+        long delay = spec.getTime();
+        if (spec.isAbsolute()) {
+            // Absolute time - calculate delay from current time
+            long now = System.currentTimeMillis();
+            delay = spec.getTime() - now;
+            if (delay < 0) {
+                delay = 0; // Fire immediately if time has passed
+            }
+        }
+
+        try {
+            if (spec.isRepeat()) {
+                long period = spec.getTime();
+                if (period <= 0) {
+                    period = 1; // Minimum 1ms period
+                }
+                timer.scheduleAtFixedRate(task, delay, period);
+            } else {
+                timer.schedule(task, delay);
+            }
+        } catch (Exception e) {
+            scheduledTasks.remove(spec);
+            throw new TVTimerScheduleFailedException("Failed to schedule: " + 
e.getMessage());
+        }
+
+        return spec;
+    }
+
+    public long getGranularity() {
+        return 1L; // 1 millisecond granularity
+    }
+
+    public long getMinRepeatInterval() {
+        return 1L; // 1 millisecond minimum repeat
+    }
+
+    public void deschedule(TVTimerSpec spec) {
+        if (spec != null) {
+            TimerTask task = (TimerTask) scheduledTasks.remove(spec);
+            if (task != null) {
+                task.cancel();
+            }
+        }
+    }
+
+    public void shutdown() {
+        timer.cancel();
+        scheduledTasks.clear();
+    }
+}


=====================================
src/libbluray/bdj/java/javax/tv/util/TVTimerSpec.java
=====================================
@@ -23,14 +23,13 @@ import java.util.Enumeration;
 import java.io.Serializable;
 import java.util.Vector;
 
-import org.videolan.Logger;
-
 public class TVTimerSpec implements Serializable
 {
     private boolean absolute;
     private boolean regular;
     private boolean repeat;
     private long    time;
+    private Vector listeners = new Vector(); // TVTimerWentOffListener
 
     public TVTimerSpec() {
         absolute = true;
@@ -56,15 +55,34 @@ public class TVTimerSpec implements Serializable
     }
 
     public void addTVTimerWentOffListener(TVTimerWentOffListener l) {
-        Logger.unimplemented(TVTimer.class.getName(), 
"addTVTimerWentOffListener");
+        if (l != null && !listeners.contains(l)) {
+            listeners.addElement(l);
+        }
     }
 
     public void removeTVTimerWentOffListener(TVTimerWentOffListener l) {
-        Logger.unimplemented(TVTimer.class.getName(), 
"removeTVTimerWentOffListener");
+        if (l != null) {
+            listeners.removeElement(l);
+        }
     }
 
     public void notifyListeners(TVTimer source) {
-        Logger.unimplemented(TVTimer.class.getName(), "notifyListeners");
+        TVTimerWentOffEvent event = new TVTimerWentOffEvent(source, this);
+        // Copy to avoid ConcurrentModificationException
+        Vector listenersCopy;
+        synchronized (listeners) {
+            listenersCopy = new Vector(listeners);
+        }
+        Enumeration e = listenersCopy.elements();
+        while (e.hasMoreElements()) {
+            TVTimerWentOffListener listener = (TVTimerWentOffListener) 
e.nextElement();
+            try {
+                listener.timerWentOff(event);
+            } catch (Exception ex) {
+                System.err.println("TVTimerSpec: Exception in listener: " + 
ex);
+                ex.printStackTrace();
+            }
+        }
     }
 
     public void setAbsolute(boolean absolute) {


=====================================
src/libbluray/bdj/java/org/videolan/BDJXletContext.java
=====================================
@@ -30,6 +30,8 @@ import java.security.PrivilegedAction;
 
 import javax.microedition.xlet.UnavailableContainerException;
 
+import javax.tv.util.TVTimerImpl;
+
 import org.bluray.ui.FrameAccurateAnimation;
 import org.dvb.application.AppID;
 import org.dvb.application.AppProxy;
@@ -282,6 +284,14 @@ public class BDJXletContext implements 
javax.tv.xlet.XletContext, javax.microedi
         return sceneFactory;
     }
 
+    public void setTVTimer(TVTimerImpl tvt) {
+        tvTimer = tvt;
+    }
+
+    public TVTimerImpl getTVTimer() {
+        return tvTimer;
+    }
+
     public static Object getXletDefaultLook(String key, Class defClass) {
         BDJXletContext ctx = BDJXletContext.getCurrentContext();
         if (ctx == null) {
@@ -492,6 +502,9 @@ public class BDJXletContext implements 
javax.tv.xlet.XletContext, javax.microedi
             callbackQueue.shutdown();
             userEventQueue.shutdown();
             mediaQueue.shutdown();
+            if (tvTimer != null) {
+                tvTimer.shutdown();
+            }
         }
 
         EventQueue eq = eventQueue;
@@ -516,6 +529,7 @@ public class BDJXletContext implements 
javax.tv.xlet.XletContext, javax.microedi
             callbackQueue = null;
             userEventQueue = null;
             mediaQueue = null;
+            tvTimer = null;
         }
         synchronized (this) {
             threadGroup = null;
@@ -546,5 +560,6 @@ public class BDJXletContext implements 
javax.tv.xlet.XletContext, javax.microedi
     private BDJActionQueue callbackQueue;
     private BDJActionQueue userEventQueue;
     private BDJActionQueue mediaQueue;
+    private TVTimerImpl tvTimer = null;
     private static final Logger logger = 
Logger.getLogger(BDJXletContext.class.getName());
 }



View it on GitLab: 
https://code.videolan.org/videolan/libbluray/-/commit/ef4a9b88a263b66ffd7b82e8c1d1efb253852daa

-- 
View it on GitLab: 
https://code.videolan.org/videolan/libbluray/-/commit/ef4a9b88a263b66ffd7b82e8c1d1efb253852daa
You're receiving this email because of your account on code.videolan.org.


VideoLAN code repository instance
_______________________________________________
libbluray-devel mailing list
[email protected]
https://mailman.videolan.org/listinfo/libbluray-devel

Reply via email to