14

The API specification reads as follows for the WebView constructor that allows private browsing to be enabled:

(from http://developer.android.com/reference/android/webkit/WebView.html)

WebView(Context context, AttributeSet attrs, int defStyle, boolean privateBrowsing)

This constructor was deprecated in API level 17. Private browsing is no longer supported directly via WebView and will be removed in a future release. Prefer using WebSettings, WebViewDatabase, CookieManager and WebStorage for fine-grained control of privacy data.

As of API 19 (KitKat) private browsing is disabled. Attempting to invoke this constructor with a value of true results in an IllegalArgumentException.

The alternatives suggested will not be even marginally effective in replicating the behavior of private browsing. The CookieManager class is a singleton, with all settings being applied to the entire application. There is no "fine grained control of privacy data" with this approach. The only control provided by CookieManager is the ability to disable cookies altogether, for EVERY WebView present in the app. This change means that third-party browsers are no longer able to replicate the private browsing feature of Google's own browser in any capacity.

I'd greatly appreciate any suggestions for working around this behavior. As of yet I can find nothing in the API that would make any resemblance of the former private browsing capability possible.

tliebeck
  • 816
  • 1
  • 8
  • 19
  • "This change means that third-party browsers are no longer able to replicate the private browsing feature of Google's own browser in any capacity" -- at most, it limits third-party browsers that use `WebView`. There are alternative rendering options, such as Mozilla's `GeckoView`. – CommonsWare Nov 22 '13 at 15:44
  • 1
    Thanks, I was implying use of WebView. Definitely appreciate the suggestion of GeckoView, will need to check it out. On this note, there is also a ChromeView project that has a similar aim with the Chrome engine: https://github.com/pwnall/chromeview I did read that this project adds 30+MiB to the APK size though (have not personally tried it though). I believe both ChromeView and GeckoView are in their early stages of development though. – tliebeck Nov 22 '13 at 16:50

1 Answers1

3

In addition to what I have in the comment, this is another place where having multiple processes is justified. Since CookieManager is a singleton, separate processes will have separate CookieManager instances. "Private browsing" WebView instances could be in a separate process from the "regular browsing" WebView instances.

This does have downsides:

  • They cannot be in the same activity, as a View from one process cannot be rendered in another process. So, if the UI metaphor for the browser implies several WebView widgets in a single activity (e.g., tabs), that UI metaphor will need to be tweaked to allow for "context switching" between regular and private browsing.

  • This will consume more system RAM, which is bad for the user, albeit good for the developer (less likelihood of OutOfMemoryError exceptions).

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • Thanks for the suggestion...in my own case, I wouldn't mind using a second process for private browsing, it would even add an additional layer of security. The CookieManager implementation unfortunately seems to cause a problem here though, as it uses a database stored in the application's internal data directory at a specific location. Both CookieManager instances would attempt to read/write from that same database. I don't think it's possible to create a second user id in a single app (but would love to be wrong). – tliebeck Nov 22 '13 at 16:59
  • @tliebeck: "as it uses a database stored in the application's internal data directory at a specific location" -- while true, the key is whether `setAcceptCookie(false)` trumps the existence of the database. One hopes that it would. "Both CookieManager instances would attempt to read/write from that same database" -- in theory, `setAcceptCookie(false)` would cause the process to not touch that database. And, even if they do, if the database is SQLite, multiple processes can hit that safely. – CommonsWare Nov 22 '13 at 17:02
  • Thanks, yes, it's a SQLite database. I definitely don't want the private-browsing process to be able to access cookies potentially set while in "normal" browsing mode. I still need to accept cookies in private browsing mode though (they need only survive for the session), but I can't call setAcceptCookie(false). The CookieSyncManager may wind up being useful here, but it's a bit thin on documentation of its behavior. If its stopSync() method eliminates any chance of synchronizing with that database, your solution might work. – tliebeck Nov 22 '13 at 17:16
  • So far I've not been able to make the Cookie(Sync)Manager behave as desired. When the second (private browsing) process completes, the cookies are synchronized. Still need to play with it a bit more and actually dig into the Android code. – tliebeck Nov 26 '13 at 11:22
  • I know this topic is quite old but I'm facing the same issue. I'd like to handle multiple webview with some in "normal" browsing mode and some others in private browsing mode. Did you find any reliable solutions or workaround? I tried to save all cookies in Room db and restore it everytime I want a "normal" browsing mode but didn't succeed unfortunately. – Yogi Bear Sep 30 '18 at 19:36
  • @tliebeck Hi, I'm a bit late to the party, but I would really appreciate if you share the solution you had ended up with. – Oleksandr Berdnikov May 07 '19 at 18:24
  • found any solution for private browsing? – Bharat Kumar Jun 02 '21 at 10:48