Menu

Remote viewing

Remote viewing allows apps to send the device's current screen to a remote server. It is part of the remote support features, which also includes remote injection.

The remote viewing APIs are accessed through the native (C) Remote Desktop library.

Capture options

The Remote Desktop library allows a device admin to capture the screen content. Screen content can be accessed through two different methods:

  • Surfaceflinger: Android's composition engine that composes the UI content and updates to the display.
  • framebuffer: Read-only access to the Linux framebuffer device (fb0) used to show graphics on the display.

Which method you use depends on:

  • Availability: Most newer devices do not support framebuffer, so you can use only Surfaceflinger.
  • Desired frame rate
  • Accuracy needed: For example, when wallpaper is on one layer, status bar on another, and all other UI elements on a third layer, framebuffer can miss some content.

Your app can choose the approach at runtime.

Secure screens

Through Android's WindowManager.LayoutParams, an app has the option to indicate whether its displayed content is secure. Apps can use the FLAG_SECURE setting to prevent its content from appearing in screenshots or from being viewed on non-secure displays.

If an app has turned on this setting for its displayed content, you cannot use the Knox remote viewing feature to capture the app's content. One option is to work with the app provider so that the app content can be remotely viewed for enterprise support and troubleshooting purposes. You could suggest that the app provider either:

  • remove FLAG_SECURE from content that does not need to be secured
  • conditionally mark content as secure depending on whether the content is displayed in an enterprise context

Set up remote capture

Your app registers a listener to receive callback notifications when the screen changes. This way, the app doesn’t have to poll continuously for any change in the screen. In the listener, your app also captures the screen content.

When a screen change occurs, the Remote Desktop module sends a screenChanged callback and waits for your app to request a capture. For any subsequent screen changes, no new callback is sent until the capture request for the outstanding callback is received.

To set up remote capture:

  1. Get an instance of the RemoteDesktop class.
  2. Set the height, width, and pixel format for the screen to be captured.
  3. Start remote capture.
  4. Get the file descriptor and file descriptor type of the screen that will be captured
  5. Map the file descriptor to memory, which can be read later.
  6. Register the listener that will receive the callbacks.

Here is sample code showing how to do this:

IRemoteDesktop mRemoteDesktop = IRemoteDesktop::getInstance();
if (res) {
    mRemoteDesktop - > setScreenInfo(width, height, pixelFormat);
}
bool res = mRemoteDesktop.init();
mRemoteDesktop - > getFrameBufInfo( & mFileDesc, & mFileDescType)
mFrame = (unsigned short * ) mmap(0, mFrameBufferSize, PROT_READ, MAP_PRIVATE, mFileDesc, offset);
mRemoteDesktop - > setListener(remoteDesktopListener);

The pixelFormat value must be one of:

  • PF_BGRA_8888
  • PF_RGB_565
  • PF_RGBA_8888
  • PF_UNKNOWN

To get the pixelFormat values supported for your device, call the API getDefaultScreenInfo.

Capture a screen

You capture the screen in the listener that waits for the callback notification. Call the API captureScreen to get the dirty (changed) regions.

void screenChanged() {
    DirtyRegion dirtyRegion;
    bool result = mRemoteDesktop - & gt;
    captureScreen(dirtyRegion);
    if (result) {
        // successfully captured the screen
    }
}