Privacy and video

Disabling video

Video recording can be disabled completely using VideoEnabled launch option. See configuration for more info.

Protect activities

You can protect any activity and prevent it from being recorded by adding it's class to the list of secure activities. Whenever user navigates to such activity, we substitute the actual screen content with black frames and stop recording touch events.

!Java

Bugsee.addSecureActivity(MySecretActivity.class.getName());

!Kotlin

Bugsee.addSecureActivity(MySecretActivity::class.java.getName())

Activities with system flag FLAG_SECURE are protected from video and touches recording without necessity to call any Bugsee methods. This flag can be set to activity in the following way.

!Java

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE);
    //...
}

!Kotlin

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    window.setFlags(WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE)
    //...
}

Protecting views

You can prevent any view from being recorded by adding it to the list of secure views. When such views are visible, we substitute actual view with black rectangle in video frame.

Marking view as protected in xml layout

Protected views can be marked in xml layout by adding app:bugsee_secure attribute to the protected view. This attribute can be set to boolean or reference to boolean value. In order to prevent showing Lint warning, related to the attribute, you can add tools:ignore="MissingPrefix" line to your protected view declaration. Protected view must have id attribute.

<!-- LinearLayout is used only for example -->
<LinearLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto" <!-- You can use arbitrary name instead of "app" -->
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <View android:id="@+id/my_secret_view1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:bugsee_secure="true" <!-- Boolean value -->
        tools:ignore="MissingPrefix"/>

    <View android:id="@+id/my_secret_view2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:bugsee_secure="@bool/enable_bugsee_hide" <!-- Reference to boolean value -->
        tools:ignore="MissingPrefix"/>
</LinearLayout>

Then it is enough to call one method in code of your activity just after setContentView() method call.

!Java

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.your_layout_name);

    Bugsee.addSecureViews(R.layout.your_layout_name, this);
}

!Kotlin

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.your_layout_name)

    Bugsee.addSecureViews(R.layout.your_layout_name, this)
}

Marking view as protected in code

The alternative approach is to mark each protected view in code.

!Java

Bugsee.addSecureView(mySecretView);
// View is substituted by black rectangle in video.
Bugsee.removeSecureView(mySecretView);

!Kotlin

Bugsee.addSecureView(mySecretView)
// View is substituted by black rectangle in video.
Bugsee.removeSecureView(mySecretView)

Marking view as protected in Jetpack Compose

In addition we support a way to mark your custom sensitive views so they will be hidden from the recorded video. We provide BugseeProtect composable function for this (BugseeProtect.kt).

!Kotlin

setContent {
    ...
    val secureContent = @Composable {
        Text(text = "Confidential.")
    }

    BugseeProtect(
        contentToHide = { secureContent() }
    )
    ...
}

Obscuring contents

Sometimes application may contain too many elements with sensitive data. Marking all the views in such app as protected maybe quite overwhelming and time consuming. In these cases you can instruct Bugsee to obscure the whole screen by lowering resolution of the captured video. In this case, you won't be able to see the text on the screen, but you will be able to follow user navigation.

To achieve this, try setting VideoScale to a value between 0.1 and 1.0.

Protected web page elements

You can also prevent any web page element, shown in WebView, from being recorded by adding class="bugsee-hide" to it.

<input type="text" class="bugsee-hide">

Elements with type="password" are not recorded by default. If you want such web page element to be recorded, add class="bugsee-show" to it.

<input type="password" class="bugsee-show">

Bugsee detects WebViews automatically, but if you use WebView.setWebViewClient() method, it is necessary to call Bugsee.addSecureWebView() method to prevent recording of protected web page elements in this WebView.

!Java

WebView webView;
// Initialize WebView
//...
webView.setWebViewClient(new WebViewClient());
Bugsee.addSecureWebView(webView);

!Kotlin

var webView = WebView(activityContext)
// Initialize WebView
//...
webView.webViewClient = WebViewClient()
Bugsee.addSecureWebView(webView)

There is one more case, when it is necessary to call Bugsee.addSecureWebView() method - if you add WebView to Activity dynamically and set ViewGroup.OnHierarchyChangeListener to the WebView parent.

!Java

public class WebViewActivity extends BaseActivity {
  @Override
    protected void onResume() {
        super.onResume();

        ViewGroup contentContainer = (ViewGroup)findViewById(R.id.content_container); // ViewGroup in Activity layout.
        contentContainer.setOnHierarchyChangeListener(mHierarchyChangeListener);
        WebView webView;
        // Initialize WebView
        //...
        contentContainer.addView(webView);
        Bugsee.addSecureWebView(webView);
    }

    private final ViewGroup.OnHierarchyChangeListener mHierarchyChangeListener = new ViewGroup.OnHierarchyChangeListener() {
        //...
    };
}

!Kotlin

class WebViewActivity : BaseActivity() {
    override fun onResume() {
        super.onResume()
        val contentContainer =
            findViewById<View>(R.id.content_container) as ViewGroup // ViewGroup in Activity layout.
        contentContainer.setOnHierarchyChangeListener(mHierarchyChangeListener)
        var webView = WebView(this)
        // Initialize WebView
        //...
        contentContainer.addView(webView)
        Bugsee.addSecureWebView(webView)
    }

    private val mHierarchyChangeListener: OnHierarchyChangeListener =
        object : OnHierarchyChangeListener {
            //...
    }
}

Protecting by coordinates

You can also protect rectangle on screen from being recorded by adding it to the list of secure rectangles. It can be especially useful in games, since there is no views there which can be made secure, and objects are drawn on canvas in case of 2D and on surface in case of 3D.

!Java

// Add secure rectangle.
Bugsee.addSecureRectangle(new Rect(100, 100, 200, 200));
// Get all secure rectangles.
ArrayList<Rect> secureRects = Bugsee.getAllSecureRectangles();
// Remove single rectangle from the list of secure rectangles.
Bugsee.removeSecureRectangle(new Rect(100, 100, 200, 200));
// Clear the list of secure rectangles.
Bugsee.removeAllSecureRectangles();

!Kotlin

// Add secure rectangle.
Bugsee.addSecureRectangle(Rect(100, 100, 200, 200))
// Get all secure rectangles.
val secureRects: ArrayList<Rect> = Bugsee.getAllSecureRectangles()
// Remove single rectangle from the list of secure rectangles.
Bugsee.removeSecureRectangle(Rect(100, 100, 200, 200))
// Clear the list of secure rectangles.
Bugsee.removeAllSecureRectangles()

Note, that secure rectangle coordinates remain the same after screen orientation change. But if necessary you can remove old secure rectangles and add new ones when, for example, Activity is being recreated on orientation change.

Going dark

In some rare cases you might want to conceal the whole screen and stop recording events completely. The following APIs will come in handy, no data is being gathered between the calls to pause and resume.

The following APIs will come in handy, no video or touch events are being gathered between the calls to pause() and resume() below:

!Java

// To stop video recording use   
Bugsee.pause();

// No touches are recorded, black frame is being recorded instead of actual data in the video.

// And to continue
Bugsee.resume();

!Kotlin

// To stop video recording use   
Bugsee.pause()

// No touches are recorded, black frame is being recorded instead of actual data in the video.

// And to continue
Bugsee.resume()