Implementation of Web Support in Embedded Linux smart device applications (2)

Source: Internet
Author: User
Tags javascript extension
A series of articles composed of two articles mainly explain how to add Web Support to embedded Linux smart device applications. Section 1st describes how to provide support for conventional web functions on devices. This article is part 1, which focuses on how to enable web programs running on embedded devices to support unique features of devices. This document uses four application scenarios as an example to describe how to modify the kernel code of the browser to implement the function of combining local applications with the Web.

Association between web and local applications

Although Web support has been used in Embedded Linux smart devices to solve many problems, some special features related to devices cannot be provided by web support. For example, the audio and video playback function in the advertising machine, the pattern recognition function of the bar code scanner, and communication with certain peripherals. These are not included in HTML and browser standards, but must be supported by local applications. Since we want to use web and B/S technologies to implement our applications, these local application functions should also be controlled by web. For example, the actual playback of a video on an advertisement machine is implemented by a local application, but the Web determines when and where the video is played. The editing of the ad page content should also be reflected in the HTML of the webpage, without the need for another playback control mechanism.

However, if you want to control local applications through the Web, there is a problem. There is no unified mechanism for calling these local applications. Some may be driven, some may be through I2C or serial port communication ports, some may be libraries provided by third parties, and some may be communication with other processes. It can be said that, apart from their mostly C/C ++ language development, there is almost nothing in common.

Now, when qwebview renders a webpage, how can we associate some specific HTML written on the webpage with our C/C ++ code. Fortunately, the QT-encapsulated WebKit provides a variety of methods to enable this association. Next, we will take several application scenarios as an example to discuss several implementation methods for the association between web and local applications.

Method for intercepting a request

First, we will introduce the First Application Scenario: an embedded smart device needs to implement the following functions. When you click the "Update" link on the webpage, the device will download and update the specified firmware.

To implement this function, the client browser needs to start the system update process after the user clicks a specific link. This includes obtaining the latest firmware address, downloading it, and updating the device. The update process of firmware is related to the hardware of the device. The standard browser cannot implement this function. Therefore, we must "intercept" the user's request and then use the local code to complete the update process.

To intercept the user's HTML request, we first analyze the qwebview structure.

Figure 1. Structure of qwebview
 

Qwebview uses qwebpage to implement pages, and qwebpage uses qwebframe to implement page elements. When the page sends a navigation request, qwebpage will process it. At this time, a function will be called:

Bool qwebpage: acceptnavigationrequest (qwebframe * frame, const qwebnetworkrequest & request, qwebpage: navigationtype type)

This function obtains the page elements, request content, and type of the event when a navigation request occurs. If the function returns false, the browser ignores this request.

We can derive a subclass from qwebpage, override acceptnavigationrequest, and process the content of a specific request. Assume that the target address is http://xxxx.com/update/firmware.bin. the actual address is as follows:

Listing 6. definition and implementation of the acceptnavigationrequest Function

Class qmywebpage: Public qwebpage {protected: bool acceptnavigationrequest (qwebframe * frame, const qwebnetworkrequest & request, qwebpage: navigationtype type );......}; qmywebpage: acceptnavigationrequest (qwebframe * frame, const qwebnetworkrequest & request, qwebpage: navigationtype) {If (type = qwebpage: navigationtypeformsubmitted) {qstring STR = url = request. URL (). PATH (); // if the target is if (STR = "http://xxxx.com/update/firmware.bin ") {// get the firmware address from link get firmware ADDR from path // download firmware // update the device firmware update firmware // return false so that the browser will not process the request again and return false; }} return qwebpage: acceptnavigationrequest (frame, request, type );}

The obtained, downloaded, and updated firmware section in the above implementation section is expressed in descriptive text. It is not a real implementation code. You can rewrite this part of local code as needed.

In addition to implementing specific functions, we also need to make qmywebpage used by qwebview. This is implemented through the setpage call of qwebview. You can add the following when constructing a qwebview instance:

Qwebview * webview = new qwebview (this );
Qmywebpage * page = new qmywebpage (); webview-> setpage (PAGE); // Let webview use our qwebpage

So far, we implemented when the page was clicked http://xxxx.com/update/Firmware.bin, intercepted this request, and let our local code be timely call to run.

Acceptnavigationrequest can also be used in another scenario. Some websites decide whether to provide the download service based on the device's MAC address, so that when the device requests the download link, it is required to provide the MAC address in the header information. We noticed that the acceptnavigationrequest parameter contains the qwebnetworkrequest variable. This class actually contains the header information. Although this variable is an unchangeable reference here, we can keep this information, copy one copy, add Mac information to the header information, and then enable qwebview to actively perform a download request to add custom content to the header information.

Execute the custom JavaScript method on the page

Next, we will introduce another application scenario: the handheld bar code machine is aimed at the cargo bar code. After a key scan, the cargo information is immediately displayed on the bar code machine.

This function is a typical web page query application. We can assume that the bar code is manually entered into the edit box on the web page, and then submit a request. The server returns the cargo information represented by the bar code. Therefore, if the bar code number can be filled in the edit box on the webpage and a submit is triggered after the button scan, this function can be implemented.

Qt-encapsulated WebKit can insert and execute User-Defined JavaScript on the loaded page, which is implemented through the evaluatejavascript interface of qwebframe.

Qvariant qwebframe: evaluatejavascript (const qstring & scriptsource );

The following example shows how to execute JavaScript.

Suppose there is an edit box named "code" on our page, and there is a button named "query" next to it ". After the scanner is aligned with the barcode, the user presses a button to trigger a message Response Function in the QT program form. In the message response function, you can use the following statement to set the content in the edit box:

Listing 7. Setting the Code Implementation of the edit box content

Qwebframe * frame = form. webview-> page ()-> mainframe (); qstring code = getscancode (); // call the barcode scanning function. You must implement qstring JS = qstring ("document. getelementbyid ('code '). value = \ "% 1 \";"). arg (CODE); frame-> evaluatejavascript (JS );

Next, you can use the following statement to trigger the query button:

Listing 8. Code implementation for triggering the query button

 QWebFrame *frame = form.WebView->page()->mainFrame();  QString js =  QString ( "document.getElementById('query').submit();" );  frame -> evaluateJavaScript ( js ); 

In addition to setting the content in the edit box on the webpage, you can also use the following statement to obtain the content in the edit box:

Listing 9. Code implementation for getting the content of the edit box

 QWebFrame *frame = form.WebView->page()->mainFrame();  QString s1 = frame->evaluateJavaScript ("document.getElementById ('code').name" ); 

This solves the problems encountered by the cargo query function of the bar code machine. We can allow the page to run our custom JavaScript at any time. This function will play a very important role. It actually solves the problem of local code and webpage cooperation in the Application Mode triggered by the device. However, this method can only be used for specific web pages, because the Javascript we insert must match the running environment on the web page.

Custom JavaScript Extension Method

Next we will introduce the third Application Scenario: Let's first consider this problem. What if the JavaScript code on the page needs to be supported by a local application? For example, a set-top box software needs to configure a local network (this type of application was originally implemented by writing local applications, but since we have discussed using the web method to replace the original development model, you need to consider how to implement it on the Web ). First, the page needs to obtain the current network setting method, IP address, subnet mask, DNS, and so on. It is displayed in the editing box and drop-down box on the webpage. After you have made some configurations, click the "OK" button on the webpage to make these configurations take effect.

From the page point of view, these must be implemented using JavaScript code, so we need to associate JavaScript code with Local Code. Qt supports custom JavaScript extensions, that is, you can define an object in QT and compile it into WebKit. The Javascript script on the page can directly generate this object and call its method. Qt provides a demo in the \ SRC \ 3rdparty \ WebKit \ WebCore \ bridge \ directory. The test code is in the testqtbindings. cpp file. We can refer to his method to compile a custom class:

Listing 10. Implementation Code of the custom class

Class myobject: Public qobject {q_object // define the association between attributes and functions q_property (qstring IP read IP write setip) Public: myobject () {} qstring IP () {// returns the implementation of the IP address in string mode}; void setip (qstring) {// sets the implementation of the IP address };}; // use the following code to generate an object instance: myobject * myobject = new myobject;

Then, use the following method to associate the object myobject with the object myinterface in javascript:

Listing 11. association code between C ++ and JavaScript objects

Global * Global = new global (); refptr <interpreter> interp = new interpreter (global); execstate * exec = interp-> globalexec (); // implement the association between C ++ and JavaScript objects: Global-> put (exec, identifier ("myinterface"), instance: createruntimeobject (instance: qtlanguage, (void *) myobject ));

Declare the definition of myobject in qwebframe. h and add the code in listing 11 to the constructor of qwebframe (qwebframe. cpp ). The qwebframe. h and qwebframe. cpp files are stored in the SRC \ 3rdparty \ WebKit \ QT \ API directory. After re-compiling the WebKit module, you can use myinterface on the webpage to call the method of the object myobject. The called JavaScript code is as follows:

When you need to obtain the IP Address:

STR = myinterface. IP;

When you need to set an IP Address:

Myinterface. IP = STR;

The above code is just an example of getting and setting IP addresses. Other methods such as masks and DNS can be used.

Any local functions implemented by embedded smart devices using C/C ++ can be called using JavaScript in the preceding method. This extension allows the browser to explain and execute any functions we want, and almost removes the obstacle of Combining web and local code. Encapsulate local code that implements specific functions into libraries and modules, and then use the web for upper-layer architecture and coupling, which will greatly reduce the difficulty of software development for Embedded Linux smart devices. In particular, for applications that often need to update features, the firmware needs to be refreshed before. Now, you only need to update the web page on the remote server.

How to compile WebKit plugin

In addition to custom JavaScript objects, we sometimes use custom webpage elements. On PC, Flash is the most typical web page element. Flash is not an HTML standard, but it can be used as a plug-in for the browser to explain these specific labels.

Last Application Scenario: Taking the advertising machine as an example, we mentioned the video playing function of the advertising machine before. Different platforms play videos in different ways, and web pages do not define the video playing standard as they define images. Therefore, an advertisement machine is an embedded device different from a PC, the video playback function must be implemented using local code. When we use web pages to organize the screens of advertising machines, the video part should become a part of the web page like images and text, which can be controlled through HTML definition. Html provides the label "object" to facilitate the implementation of some special objects. For example:

 < object data="yahtzee.gif" type="image/gif" title="A Yahtzee animation"                                  width=200 height=100 > 

If our Browser allows us to insert a custom object to a webpage in a similar way, this problem can be solved.

Qt supports adding custom plug-ins to WebKit. In the frameloaderclientqt. cpp file, find the following code snippet:

Listing 12. frameloaderclientqt. cpp code snippet

 if ( mimeType == "application/x-qt-plugin"    || mimeType == "application/x-qt-styled-widget" )  {         object = m_WebFrame->page()->createPlugin( classid, qurl, params, values ); 

The code above shows that if an object in HTML sets its type to application/X-QT-plugin or application/X-QT-styled-widget, qt recognizes and requires qwebpage to create a plug-in by calling the createplugin function of qwebpage. The function is defined as follows:

 QObject *QWebPage::createPlugin ( const QString &classid, const QUrl &url,      const QStringList &paramNames, const QStringList &paramValues ); 

We designed the following HTML to identify our objects:

 <object type="application/x-qt-plugin" classid="VideoPlayer" width=800                      height=600 file="kfc.avi" ></object> 

We set to insert a videoplaye object in the webpage, and set parameters such as width and height and the file to be played. Because we set the object type to application/X-QT-plugin, when the browser encounters this HTML code, it will call the createplugin function of qwebpage. This function is required to return a form. This form is regarded as a standard webpage object, which is embedded into the web page like the edit box and drop-down box.

We first derive our own object from qwebpage to implement createplugin:

Listing 13. Implementation of the createplugin Function

Class qmywebpage: Public qwebpage {protected: qobject * createplugin (const qstring & classid, const qurl & URL, const qstringlist & paramnames, const qstringlist & paramvalues );......}; qobject * qmywebpage: createplugin (const qstring & classid, const qurl & URL, const qstringlist & paramnames, const qstringlist & paramvalues) {If (classid = "videoplayer ") {// create a custom form with video playback function, videowindow * window = new videowindow (); // configure parameters such as width = 800, window-> setgeometry (........); window-> setsourcefile (......); return window; // return the created form }...}

Like the method used to intercept a request, we need to use our qmywebpage:

Qwebview * webview = new qwebview (this); qmywebpage * page = new qmywebpage (); webview-> setpage (PAGE); // Let webview use our qmywebpage

Note that you need to enable the plug-in enabling option before loading the page. The method is as follows:

 QWebSettings* setting = Webview->settings ();  setting->setAttribute ( QWebSettings::PluginsEnabled, true ); 

So far, we have created our own webpage element: object of the videoplayer type. Web pages can flexibly use their own features on the embedded platform, just like using standard web page elements. Of course, you do not have to define this webpage element using application/X-QT-plugin or application/X-QT-styled-widget, qt also supports plug-ins using types instead of the two or dynamically linked libraries, so that you can support non-QT custom objects such as flash, for more information, see the QT documentation.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.