Replacement for `__system_property_get` in Android L NDK - android-ndk-r5

As of the Android L NDK, __system_property_get is removed (https://groups.google.com/a/chromium.org/forum/#!topic/chromium-reviews/keQP6L9aVyU). Is there another API in the Android L NDK to access the same property values?

I went with popen as detailed in the answer at https://stackoverflow.com/a/478960/2833126 to run getprop. Something like
std::string command = "getprop ro.product.model";
FILE* file = popen(command.c_str(), "r");
if (!file) {
// error
}
// read the property value from file
pclose(file);

what about
androidVersion = system("getprop ro.build.version.release");
printf("%s", androidVersion.c_str());

Related

What is the C++ iostream to creating a file with O_EXCL?

I want to create an output file in a threadsafe manner, and only if it does not exist. I want to use the file system for synchronization. With open() I would use the flags O_RWRONLY|O_CREAT|O_EXCL. Is there a way to do this in C++17 using the iostream or fstream ?
Prior to C++23 there is no way of opening an ofstream in exclusive mode.
Workaround: Use std::fopen which has this capability since C++17.
Example:
#include <cstdio>
// Mode "x" to make it fail if it already exists
std::FILE* fp = std::fopen("filename", "wx");
if(fp) {
// created exclusively
// work with fp ...
std::fclose(fp);
}
If you really want an ofstream you could create a helper function:
template<class Stream>
Stream open_exclusively(const std::string& filename) {
Stream rv;
if(std::FILE* fp = std::fopen(filename.c_str(), "wx"); fp) {
std::fclose(fp);
// overwrite the file that was created exclusively:
rv.open(filename);
} else {
// could not create file exclusivly, set the failbit in the stream:
rv.setstate(Stream::failbit);
}
return rv;
}
int main() {
auto os = open_exclusively<std::ofstream>("filename");
if(os) {
std::cout << "file created exclusively\n";
}
}
Demo
Edit:
Even though the above demo is compliant and works on all platforms I've tested it - wine (v6.16) can't handle it, so I opened a bug report at bugs.winehq.org. You can follow the progress here:
Standard library call fopen(..., "wx") not recognized - causes destruction of data
Edit 2:
The Wine bugfix ucrtbase: Add support for x mode in fopen is now included in Wine 6.20 so after upgrading to 6.20 (or later), this will be working as it should in Wine too.
From C++23 you can use the std::ios::noreplace openmode:
std::ofstream os("filename", std::ios::noreplace);
if(os) {
std::cout << "file created exclusively\n";
}

VLC: saving a stream to a file

This code works with VLC 2.2.8 but it does not with VLC 3.0.9.2
if (it->second.handle && it->second.fDump) {
// Video/audio + file dump -> duplicate stream
transcode = "#duplicate{ dst=file{ dst=" + string(it->second.fDump) + " }, dst=display }";
}
else if (it->second.handle == NULL) {
// No video + file dump -> single stream
transcode = "#standard{ access=file, dst='" + string(it->second.fDump) + "' }";
}
I am focusing on the second branch and I wish to receive suggestions, thanks.
UPDATE:
It does not work means that it does not throw any error nor warning but it does not create the file. It seems, it ignores the option.
UPDATE 2:
I suspect that the saving option is ignored because I see this line in the application log which is related to the GPU but I have no way to see the video output:
avcodec: Using OpenGL/VAAPI backend for VDPAU for hardware decoding
It is not required decoding the stream but simply saving.
UPDATE 3:
I do not use the graphic interface but the command line and this works:
vlc rtsp://172.18.2.60:554/Streaming/Channels/1 --rtsp-user=$user --rtsp-pwd=$passwd \
--sout="#file{dst=test.mp4}" --vout=dummy -Idummy --ignore-config --quiet \
--rtsp-frame-buffer-size=500000 --network-caching=4000
However, trying to send the same trough VLC library API, it does not save the file. Then the issue should be in this piece of code which works with VLC 2.2.8:
it->second.p_lib = libvlc_new((int)argsCount, p_args);
if (!it->second.p_lib) {
HVLog("Cannot initialize VLC engine");
return -1;
}
// Set up logging
libvlc_log_set(it->second.p_lib, s_vlc_logcb, nullptr);
libvlc_media_t *p_url = libvlc_media_new_location(it->second.p_lib, url.c_str());
it->second.p_player = libvlc_media_player_new_from_media(p_url);
libvlc_media_release(p_url);
if (it->second.handle)
libvlc_media_player_set_hwnd(it->second.p_player, it->second.handle);
if (libvlc_media_player_play(it->second.p_player) < 0) {
HVLog("HVPlayOpen(%p, %d): cannot play stream %s", p_cam, channel, url.c_str());
return -1;
}
return 0;
For testing, I used this code instead and it works, obviously.
char vlcstr[1024];
snprintf(vlcstr, 1024, "vlc %s --rtsp-user=%s --rtsp-pwd=%s --sout=#file{dst=%s} --vout=dummy -Idummy "
"--ignore-config --quiet --rtsp-frame-buffer-size=500000 --network-caching=4000 &",
ss.str().c_str(), p_camera->getUser().c_str(), p_camera->getPassword().c_str(), it->second.fDump);
HVLog("HVPlayOpen(%p, %d): %s", p_cam, channel, vlcstr);
system(vlcstr);
return 0;
However, I wish to use the library API not the system().
UPDATE 4:
This is the log https://pastebin.com/9zgMQiNL
SOLVED
The issue is addressed using the libvlc_media_add_option() function as show here:
https://forum.videolan.org/viewtopic.php?t=69933

Call to unavailable function 'system': not available on iOS?

I am revisiting source code from a few years back and it used to compile perfectly but now there is one error in the project I can't figure out.
I have the following code:
void AssetsManager::destroyStoragePath()
{
// Delete recorded version codes.
deleteVersion();
// Remove downloaded files
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT) || (CC_TARGET_PLATFORM == CC_PLATFORM_WP8)
FileUtils::getInstance()->removeDirectory(_storagePath.c_str());
#elif (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
string command = "rd /s /q ";
// Path may include space.
command += "\"" + _storagePath + "\"";
system(command.c_str());
#else
string command = "rm -r ";
// Path may include space.
command += "\"" + _storagePath + "\"";
system(command.c_str());
#endif
}
NS_CC_EXT_END;`
I get the following error:
"Call to unavailable function 'system': not available on iOS"
How do I fix this error?
There are several way besides system. You may use NSTask (Process in swift)

Java 8 issues printing PS to network printer

Got a weird question for you. Recently upleveled my old project from java 7(jdk1.7.0_10) to java 8(1.8.0.91.x86_64). In java 7 it printed the post script file with no issues and now it is printing the postscript file as plain text instead of converting the file. This is on a redhat linux environment. Simply I am trying to print a string containing a post script file of a file itself.
Here is my original code
DocFlavor flavor = DocFlavor.INPUT_STREAM.POSTSCRIPT;
PrintService pService = PrintServiceLookup.lookupDefaultPrintService();
// In a field environment, send to the printer
if (System.getenv("USER_DEFINED_RELTOP") == null || pfr.exists()) {
if (pService.getName().isEmpty()) {
LOGGER.error("No printer selected");
} else {
LOGGER.info("Printing to " + pService.getName());
DocPrintJob pj = pService.createPrintJob();
try {
InputStream is = new ByteArrayInputStream(data.getBytes("UTF8"));
Doc doc = new SimpleDoc(is, flavor, null);
PrintJobWatcher pjw = new PrintJobWatcher(pj);
pj.print(doc, null);
pjw.waitForDone();
is.close();
} catch (PrintException | IOException e) {
LOGGER.error(e);
} // try block
} // no printer selected
// Otherwise, send to a file
} else {
That worked fine in java 7, I updated it to the oracle spec found here for java 8.
https://docs.oracle.com/javase/8/docs/api/javax/print/PrintService.html#createPrintJob--
https://docs.oracle.com/javase/8/docs/technotes/guides/jps/spec/printing.fm6.html
DocFlavor psFlavor = DocFlavor.INPUT_STREAM.POSTSCRIPT;
PrintRequestAttributeSet attrs = new HashPrintRequestAttributeSet();
attrs.add(MediaSizeName.ISO_A4);
PrintService[] pservices = PrintServiceLookup.lookupPrintServices(psFlavor,
attrs);
File pfr = new File(PFR_INDICATOR);
// In a field environment, send to the printer
if (System.getenv("USER_DEFINED_RELTOP") == null || pfr.exists()) {
//Check we have a printer capable of post script
if (pservices.length > 0) {
LOGGER.info("Printing to " + pservices[0].getName());
DocPrintJob pj = pservices[0].createPrintJob();
try {
InputStream fis = new ByteArrayInputStream(data.getBytes("UTF8"));
//byte[] ba =data.getBytes("UTF8");
Doc doc = new SimpleDoc(fis, psFlavor, null);
LOGGER.info("Doc Flavor " + doc.getDocFlavor());
PrintJobWatcher pjw = new PrintJobWatcher(pj);
LOGGER.info("PrintJob Attributes : " + pj.getAttributes());
pj.print(doc, attrs);
pjw.waitForDone();
fis.close();
} catch (IOException e) {
LOGGER.error(e);
NotificationDialog.show(NotificationDialog.NOTICE_TYPE.ERROR, PRINT_ERROR);
} catch (PrintException e) {
LOGGER.error(e);
}
} else { // no printer selected
This gives me an error java.awt.print.PrinterIOException: java.io.IOException: /usr/bin/lpr: where it looks to not find lpr.
If I keep it the way it was originally (not write to file) it prints the postscript as plain text even if adding the check to check if the printer is post script capable. If I use the new way of printing file I get a lpr not found error. If I print the PS document using the command lpr it converts it as expected and prints fine. If I use lpr -l that doesn't format it prints it document as plain text as well.
Any suggestion/help would be great. I am lost on what to do. I really don't want to convert it to an image and print that.
At a guess I'd say that your printer is an HP or at least PCL + PS printer, not a pure PostScript-only printer.
In that case you generally need to prepend the PostScript with a language selection PJL string. If you don't do this then it usually defaults to PCL and if you don't send any PCL commands (which all begin with 0x1B) then everything is treated as plain ASCII text. That would explain why both your application and lpr -l end up writing text, but lpr itself doesn't (presumably it adds the PJL).
You could try prepending the PostScript file with something like:
%-12345X#PJL JOB
#PJL ENTER LANGUAGE=POSTSCRIPT
NB the first byte there, before the % should be a 0x1b ESC character, but I can't readily paste binary....
Try sending the file with lpr -l if that works then you could try your old printing method.

vlcj:: Unable to load library 'libvlc' in 64bit OS

I am using 64 bit OS Windows 7 and i have 32 bit VLC versioned 1.1.8.
I have added these libraries
jna.jar
platform.jar
vlcj-1.1.5.1.jar
I am not able to stream using jVlc
public class HelloVLC {
/**
* #param args
* #throws IOException
*/
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
System.out.println( WindowsRuntimeUtil.getVlcInstallDir());
NativeLibrary.addSearchPath("libvlc", "C:\\Program Files (x86)\\VideoLAN\\VLC");
String media = "dshow://";
String[] options = {" :dshow-vdev=Integrated Webcam :dshow-adev= :dshow-caching=200", ":sout = #transcode{vcodec=theo,vb=800,scale=0.25,acodec=vorb,ab=128,channels=2,samplerate=44100}:display :no-sout-rtp-sap :no-sout-standard-sap :ttl=1 :sout-keep"};
System.out.println("Streaming '" + media + "' to '" + options + "'");
MediaPlayerFactory mediaPlayerFactory = new MediaPlayerFactory();
final HeadlessMediaPlayer mediaPlayer = mediaPlayerFactory.newMediaPlayer();
mediaPlayer.playMedia(media, options);
}
}
I am getting the error Exception in thread "main" java.lang.UnsatisfiedLinkError: Unable to load library 'libvlc': The specified module could not be found.
Kindly help. Is there any way to get this code work in 64 bit OS????
have you tried running it with a 32-bit JVM?
if you are using windows 7 then search for a file libvlc.dll and libvlccore.dll files in to your vlc installation and add their path to code that you've written in
NativeLibrary.addSearchPath() also add...
this worked me in my case windows 7.
NativeLibrary.addSearchPath(
RuntimeUtil.getLibVlcLibraryName(), ""c:/Program Files/VideoLAN/VLC/");
Native.loadLibrary(RuntimeUtil.getLibVlcLibraryName(), LibVlc.class);
LibXUtil.initialise();
VLCj comes with automagic discovery methods, os-independent, that adds the relevent path to JNA:s search path:
NativeDiscovery nd = new NativeDiscovery();
if (!nd.discover()) {
System.out.println("VLC not found");
System.exit(-1);
}
String vlcLibName = RuntimeUtil.getLibVlcName();
String vlcLibCoreName = RuntimeUtil.getLibVlcCoreName();
Native.loadLibrary(vlcLibName, LibVlc.class);
...etc
for a good tutorial on how to load the VLC natives, see
http://capricasoftware.co.uk/#/projects/vlcj/tutorial/first-steps
(See also the previous steps in that tutorial)!

Resources