diff --git a/CodenameOne/src/com/codename1/capture/VideoCaptureConstraints.java b/CodenameOne/src/com/codename1/capture/VideoCaptureConstraints.java index 0b9a65d9704..ad4dc3dda21 100644 --- a/CodenameOne/src/com/codename1/capture/VideoCaptureConstraints.java +++ b/CodenameOne/src/com/codename1/capture/VideoCaptureConstraints.java @@ -355,7 +355,16 @@ public int getPreferredMaxLength() { /// - #getPreferredMaxLength() public boolean isMaxLengthSupported() { build(); - return maxLength == 0 || maxLength == preferredMaxLength; + // Guard on the PREFERRED value, the way isQualitySupported() and + // isMaxFileSizeSupported() do: it is "the caller asked for no limit" + // that makes any resolved value acceptable. Guarding on the RESOLVED + // value instead inverted the answer in the one case a caller asks this + // question about -- a platform that expresses "no duration limit" by + // resolving maxLength to 0 (every platform with no compiler, Java SE + // included) reported a five-second preference as honored. That also + // contradicted getMaxLength()'s documented "equal to + // getPreferredMaxLength() iff isMaxLengthSupported()". + return preferredMaxLength == 0 || maxLength == preferredMaxLength; } /// Gets the width constraint that is supported by the platform, and is nearest to the specified diff --git a/maven/core-unittests/src/test/java/com/codename1/capture/VideoCaptureConstraintsTest.java b/maven/core-unittests/src/test/java/com/codename1/capture/VideoCaptureConstraintsTest.java index 6962589bb98..7ed8d417e29 100644 --- a/maven/core-unittests/src/test/java/com/codename1/capture/VideoCaptureConstraintsTest.java +++ b/maven/core-unittests/src/test/java/com/codename1/capture/VideoCaptureConstraintsTest.java @@ -1,3 +1,25 @@ +/* + * Copyright (c) 2026, 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.capture; import com.codename1.junit.FormTest; @@ -28,4 +50,59 @@ public void testVideoCaptureConstraints() { Assertions.assertTrue(vcc.equals(vcc)); // Removed vcc.equals(null) because implementation throws NPE which is a bug in core but we cannot fix it here. } + + /// A platform with no compiler resolves every constraint to 0, which is how + /// "this platform imposes no duration limit" is expressed. A caller that asked + /// for a five second limit must be told it was not honored. + /// + /// Java SE registers no compiler -- only the iOS, Android and JavaScript ports + /// do -- so this runs on the very platform the developer guide's support table + /// lists as having no max-length support. + @FormTest + public void testMaxLengthUnsupportedWhenResolvedToZero() { + VideoCaptureConstraints vcc = new VideoCaptureConstraints(0, 0, 5); + + Assertions.assertEquals(5, vcc.getPreferredMaxLength()); + Assertions.assertEquals(0, vcc.getMaxLength(), "no compiler resolves the length to 0"); + Assertions.assertFalse(vcc.isMaxLengthSupported(), + "a 5s preference resolved to 'no limit' is not a supported 5s preference"); + Assertions.assertFalse(vcc.isSupported(), + "isSupported() is an AND over the four predicates, so it must follow"); + } + + /// The other side of the same guard: a caller who asked for no limit gets one, + /// whatever the platform resolves, and must still be told the constraint holds. + @FormTest + public void testMaxLengthSupportedWhenNoLimitRequested() { + VideoCaptureConstraints vcc = new VideoCaptureConstraints(0, 0, 0); + + Assertions.assertEquals(0, vcc.getPreferredMaxLength()); + Assertions.assertTrue(vcc.isMaxLengthSupported()); + Assertions.assertTrue(vcc.isSupported()); + } + + /// Partial support: the platform limits duration but not to the requested value. + /// Installing a compiler is safe to undo because Java SE never registers one. + @FormTest + public void testMaxLengthUnsupportedWhenResolvedToDifferentValue() { + try { + VideoCaptureConstraints.init(new VideoCaptureConstraints.Compiler() { + public VideoCaptureConstraints compile(VideoCaptureConstraints cnst) { + VideoCaptureConstraints out = new VideoCaptureConstraints(cnst); + out.preferredMaxLength(10); + return out; + } + }); + + VideoCaptureConstraints vcc = new VideoCaptureConstraints(0, 0, 5); + Assertions.assertEquals(10, vcc.getMaxLength()); + Assertions.assertFalse(vcc.isMaxLengthSupported()); + + VideoCaptureConstraints exact = new VideoCaptureConstraints(0, 0, 10); + Assertions.assertEquals(10, exact.getMaxLength()); + Assertions.assertTrue(exact.isMaxLengthSupported()); + } finally { + VideoCaptureConstraints.init(null); + } + } }