Project: titanium
Issue TIMOB-18956: Android orientation change detection is missing reverse orientation distinction
The documentation confirms that this is missing from the various places where in Android you could detect orientation change. * Ti.Gesture.orientationchange event http://docs.appcelerator.com/platform/latest/#!/api/Titanium.Gesture-event-orientationchange * Ti.Gesture.orientation property http://docs.appcelerator.com/platform/latest/#!/api/Titanium.Gesture-property-orientation * Ti.Android.Activity. requestedOrientation property http://docs.appcelerator.com/platform/latest/#!/api/Titanium.Android.Activity-property-requestedOrientation From docs: On Android and Mobile Web, returns the orientation of the current window, and *never reports the "reverse" orientations* (LANDSCAPE_RIGHT and UPSIDE_PORTRAIT). Android itself does report the reverse orientation changes, Titanium is just not surfacing this level of reporting. This deficiency prevents being able to detect precisely to which orientation has the device been rotated to with respect to a view, such as a camera view needed for barcode scanning. When the device has rotated but the view (and the object which is the subject of the scanning) has not rotated, you must be able to determine what the relative rotation is without the possibility of being 180 degrees off. Let me try to illustrate how this becomes a problem with some ASCII art and the scenario being a barcode scanning camera view in a module where the app must report to the module the orientation change. This is just an example of 1 use case where this deficiency can be seen as a problem. Let's say this is your device in portrait orientation: {noformat} A---B |a-b| || || |c-d| C---D {noformat} ABCD are the corners of the hardware, abcd are the corners of the camera view. Let's say the camera sensor is mounted such that the top-left corner of the picture is nearest to the A corner, the top-right corner of the picture is nearest to the B corner, etc. In this case, the rotation difference between the camera sensor and the camera view is 0 degrees, so the pixel at the top-left corner of the picture can go near the 'a' corner of the view, the pixel at the top-right corner of the picture can go near the 'b' corner of the view, etc. If the activity supports landscape-right orientation, then this is how your screen will look like if you rotate your device 90 degrees counter-clockwise: {noformat} B------C |a----b| || || |c----d| A------D {noformat} The important thing to realize is that the camera sensor rotated with the hardware but the view didn't, and neither did the object you are pointing the camera at. So the top-left pixel is still near the A corner as far as the camera sensor is concerned, but now that pixel needs to go to the 'c' corner of the view, otherwise from your (the user's) perspective the camera feed will look like it's rotated 90 degrees clockwise (because the object in front of the camera didn't rotate with the camera sensor). This can be achieved by the app telling the module that the activity's UI is now in landscape-right orientation, which the module will interpret not as landscape-right per se, rather as "rotate the camera feed 90 degrees counter-clockwise". I think by now it should be clear why we need to distinguish between landscape-right and landscape-left, but just for completeness -- if the activity supports landscape-left orientation as well, then this is how your screen will look like if you rotate your device 90 degrees clockwise (relative to portrait): {noformat} C------A |a----b| || || |c----d| D------B {noformat} The top-left pixel is still near the A corner as far as the camera sensor is concerned, but now that pixel needs to go to the 'b' corner of the view. In this case the module would have to rotate the camera feed clockwise by 90 degrees. If we can't distinguish between these two cases (i.e. landscape-left and landscape-right), then the best we can do is to rotate the camera feed by 90 degrees in the same direction in both cases, which will mean that the camera feed will appear off by 180-degrees (i.e. upside-down) to the user in one of those cases. Similar logic applies to portrait vs. reversePortrait. A work around would be to recreate orientation change handling in the module, however the better solution should be to improve this handling in the Titanium SDK so that the app can notify the module using Titanium SDK available functions/events about this change instead of the module needing to unnecessarily replicate Titanium SDK capabilities just to improve them. This works as expected in the iOS Titanium SDK.
Story points: 8