WebRTC getUserMedia deviceId constraint is not supported - google-chrome

I am trying to get device Id from user by using WebRTC API navigator.mediaDevices.getUserMedia. But the function throws an OverconstrainedError which has constraint property inside says deviceId. This means something was wrong with the deviceId.
However, I don't see any reason for browser to can't get device ID. Actually I haven't experienced this issue before.
Do you have any idea what would be the reason? Would it be because of the camera or is it all about the browser?

Not exactly sure what you are passing as contraints to the gUM but if you look at this code on github ( https://webrtc.github.io/samples/src/content/devices/input-output/ ), it provides a good example of toggling various media inputs and you can see in the source (or step through the code in the debugger) what the constraints are set to and how they get the deviceId - note this is not my code but is part of the webRTC samples.

Related

Unable to delete specific named cookie (Selenium WebDriver, C#, Chrome)

A number of my tests use a DeleteCookies method which does this:
chromeDriver.Manage().Cookies.DeleteAllCookies();
This was great until today, when one of the tests made the app take exception:
The required anti-forgery cookie "__RequestVerificationToken" is not present.
So I decided to delete the specific cookie in question, rather than all of them:
chromeDriver.Manage().Cookies.DeleteCookieNamed("user%40user.com");
The specified cookie was not deleted.
To verify DeleteCookieNamed actually worked at all, I deleted two of the other cookies the app creates and it worked.
When a user logs in, the app sets the name of the cookie to their username (in this case, user#user.com) ...but presumably due to URL encoding, changes # to %40.
The cookies that did delete didn't contain %40.
If it was the case that you can't delete cookies where the name contains %40, then DeleteAllCookies wouldn't have worked. Therefore I suspect my targeted cookie has dependencies, similar to how foreign key constraints work in relational databases, such that I need to delete one or more other cookies in a specific order before I can delete the specified one.
A cursory glance at Google provides me with instructions on how to delete cookies in Chrome, rather than how Chrome deletes cookies. Joy. I've run out of time today, please do you have any insights?
The way I got round this issue when I had it was to create the cookie through selenium, and then I was able to delete it. I did find it easier though not to use the # in the cookie names. Hope that helps.
This seems an appropriate work-around for my particular situation - run the CanLogIn test last, using a Playlist:
https://stackoverflow.com/a/29039261/1875540
Use Chrome DevTools:
https://chromedevtools.github.io/devtools-protocol/tot/Network/#method-deleteCookies
The code will be like this:
ChromeDriver driver;
var parameters = new Dictionary<string, object>
{
["name"] = "user%40user.com";
};
driver.ExecuteChromeCommand("Network.deleteCookies", parameters);
You can do this by Selenium DevTools as well. But since they have some problems with integrations, and you may need to upgrade the library after every google update, using the above code can be more efficient and easier.

Consistent Empty Data using MediaRecorderAPI, intermittently

I have a simple setup for Desktop Capturing using html5 libraries.
This includes a simple webpage and a chrome-extension. I am using
Extension to get the sourceId
Using the sourceId I call navigator.mediaDevices.getUserMedia to get the MediaStream
This MediaStream is then fed into an instance of MediaRecorder for recording.
This setup works most of the times, but a few times I see that requestData() on MediaRecorder instance returns blob with empty data consistently. I am clueless as to what can cause a running setup to start misbehaving sometimes.
Some weird behaviour that I noticed in the bad state:
When I try to close/refresh the window it doesn't respond.
The MediaStreamTrack object in Step 2) above is 'live' but as soon as I go to Step 3) it becomes 'muted'.
There's no pattern to it, sometimes it even happens when I request for the MediaStreams the very first time(which rules out the possibility that there could be some dangling resources eating up the contexts)
Is there anything that I am doing wrong and am unaware of? Any help/pointers would be highly appreciated!

App Widget getting hijacked by Google Sound Search?

So I'm seeing some bizarre behavior in an appwidget that I wrote.
The widget itself is quite simple - it reads a few values from persistent storage and then displays them as text. Nothing fancy in the layout - just a FrameLayout root element with some Linear Layout and TextView children.
The widget has a simple configuration activity associated with it.
The bizarre behavior is that the widget will initially show "Problem Loading Widget" after the user closes the configuration activity, and then after a few seconds it shows a "Google Sound Search" button (and clicking on the button actually does launch Google Sound Search). Then, after a few more seconds, it finally shows the expected display.
I am away from my code right now, so I'll have to wait until tonight to post code snippets. However, in the meantime, can anyone provide some insight into how such a thing could happen? Has anyone else ever experienced this? How could another widget "hijack" mine?
Thanks,
-Ron
Here are some screenshots:
There are a couple of issues with your widget and there are answers to all of them (although you didn't post any code so some of my statements are based on assumptions):
"Problem loading widget": this is the default view Android uses before the widget is initialized and the layout updated. Simply add the following line to your widget xml configuration (to show a loading message instead of the problem message):
android:initialLayout="#layout/my_cool_widget_loading_message"
If the widget shows the wrong layout then you probably have an issue in the widget's onReceive method. onReceive is called for all the widgets no matter whether the broadcast is for that specific widget. Android's AppWidgetProvider filters the broadcasts by appwidget Id and dispatches to the other methods (like onUpdate).
See also: https://developer.android.com/reference/android/appwidget/AppWidgetProvider.html#onReceive(android.content.Context, android.content.Intent).
If you override onReceive (which I assume you do), you need to call through to super.onReceive(Context, Intent) to make sure your other methods don't get calls meant for other widgets.
Now for the configuration of the widget. If you follow the Google documentation then it will all work nicely. The only improvement I'd do is what my other answer that you reference suggests (https://stackoverflow.com/a/14991479/534471). This will NOT send out two broadcasts. The setResult()/finish() part does only terminate the config Activity and let Android know whether to actually add the widget or not (depending on whether the result is RESULT_CANCELED or RESULT_OK.
From your own answer I can see why your code wouldn't work. The code is:
Intent intent = new Intent();
intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, new int[] {mAppWidgetId});
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId);
setResult(RESULT_OK, intent);
sendBroadcast(intent);
finish();
First of all there's no need to add the appWidgetId twice, use the AppWidgetManager.EXTRA_APPWIDGET_IDS version and you're good. Second you're using the same Intent to return as a result for the Activity. AFAIK it's not documented what happens when you do set an action on that Intent but my experience with Android widgets is that you need to stick exactly to the documentation or you'll end up having strange issues (like the ones you encounter). So please use two different Intents.
Activity result:
Intent resultValue = new Intent();
resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId);
setResult(RESULT_OK, resultValue);
finish();
Broadcast:
Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_UPDATE, null, this, MyWidget.class);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, new int[] {mAppWidgetId});
sendBroadcast(intent);
ok, so I figured it out. Posting here in case anyone else runs into this. I think that the Android Developer docs are a little misleading here.
The problem was that in my configuration Activity, I had this code at the end:
Intent intent = new Intent();
intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, new int[] {mAppWidgetId});
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId);
setResult(RESULT_OK, intent);
sendBroadcast(intent);
finish();
Providing an intent with the extra EXTRA_APPWIDGET_ID is recommended by the documentation provided by google.
However, that same document says that you have to update the widget's view by creating a RemoteView and calling AppWidgetManager.updateAppWidget() like so:
RemoteViews views = new RemoteViews(context.getPackageName(),
R.layout.example_appwidget);
appWidgetManager.updateAppWidget(mAppWidgetId, views);
I didn't like the idea of placing the presentation logic in both the configuration activity and the widget class, so I instead decided to broadcast an intent at the end of the configuration activity to tell the widget to redraw itself. That's why I have setResult() AND sendBroadcast() at the end of the activity. The documentation further states that the onUpdate() callback will not be called when using a configuration activity. So this seemed neccessary. I added the ACTION_APPWIDGET_UPDATE and the EXTRA_APPWIDGET_IDS to the intent so that it would trigger the onUpdate() method. This practice was recommended by this SO answer (albeit without being included in the activity result intent - but I tried separating the two and it had no effect).
Now I'm not certain exactly how the "Google Sound Search" widget got in there, nor do I fully understand the mechanics of how the intents interacted to produce the observed results. However, as soon as I replaced my code above with the code stated in the docs, the widget was updated properly.
Intent resultIntent = new Intent();
resultIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId);
setResult(RESULT_OK, resultIntent);
finish();
This seems to contradict the documentation's statement that the configuration activity must update the widget's view. Simply providing the configuration activity result as below triggers the onUpdate() method in the widget, thus allowing the widget to redraw itself. I confirmed the behavior on an emulator running API 23 and also on a Samsung device running Samsung's android flavor.

Is it possible to use the cast API from a chome app? how to bypass the receiver selection popup?

Does anyone know, is the cast API supported for use from a chrome app? It initializes fine, says there are receivers available but I can't get a session - when I call requestSession nothing happens at all, neither success nor error callbacks are called, no window is displayed.
Maybe I'm approaching this all wrong...what I'm trying to do seems like it should be relatively straight-forward, but it really seems like google has deliberately prevented this. All I'm trying to do is hook my IR remote up to my chromecast for media playback controls (play/pause/seek). Even if the requestSession method worked, it really wouldn't give the user experience I want - it would still require the user to select the receiver from the popupmenu UI whenever they want to use their IR remote - far from friendly. Instead I'd like to be able to pre-configure which chromecast the IR remote is bound to...and then it would always just connect to whatever app/session is currently running on that receiver to issue play/pause/seek commands.
I could implement this as a browser extension instead, and I'm sure I could get it functional that way...but that would be even less user-friendly (not to mention I'm already using some app-only APIs for the IR-receiving side of it which would have to be re-worked to other methods).
edit: Ok, after a bit more looking I've found this which I guess mostly answers my question https://code.google.com/p/chromium/issues/detail?id=287254 ....but the question about the popup still stands...even if using an extension is there any way to bypass the reciever-selection popup that requires user interaction?

How to take a screenshot in WP8?

How to produce a complete WP8 screenshot? By “complete” I mean “including application bar, status bar, message boxes and keyboard”.
Things I’ve tried:
GDI API that worked in WP7 (GetDC, CreateCompatibleDC, BitBlt), result - CreateCompatibleDC or CreateDCW return NULL, GetLastError says “the specified procedure could not be found”. Moreover, it seems WP8 only has the single HDC, namely 0x00dc00dc, so no off-screen GDI DCs are possible.
InvokeScreenCapture and SaveApplicationScreenShot from ShellChrome.dll – application deactivates, nothing else happens.
D3D11Device1::GetImmediateContext, ID3D11RenderTargetView::OMGetRenderTargets – OMGetRenderTargets returns NULL.
Any other ideas?
I don’t need to pass marketplace certification, so unsupported/undocumented APIs are OK.
In WP8 and under there is no way to capture the entire screen without running in TCB (requires a hacked image) and loading in libs that don't ship with any SDK.