Skip to content

Commit

Permalink
[TIMOB-26157] Android: Avoid Android 8.0 crash when applying a fixed …
Browse files Browse the repository at this point in the history
…orientation to a semi-transparent or modal window. (#10138)

- No longer supported by the Android OS. Now catches the exception and logs an error when attempting to do so.
- Removed API Level 9 checks when assigning orientation. (Min supported API Level is currently 16.)
  • Loading branch information
jquick-axway authored and hansemannn committed Jun 27, 2018
1 parent 8795d4f commit ef2912f
Show file tree
Hide file tree
Showing 4 changed files with 91 additions and 81 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,11 @@ public void setRequestedOrientation(int orientation)
{
Activity activity = getWrappedActivity();
if (activity != null) {
activity.setRequestedOrientation(orientation);
try {
activity.setRequestedOrientation(orientation);
} catch (Exception ex) {
Log.e(TAG, ex.getMessage());
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,15 +54,22 @@ public int getOrientation()
@Kroll.method
public void setOrientationModes(int[] modes)
{
int activityOrientationMode = -1;
int activityOrientationMode = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
boolean hasPortrait = false;
boolean hasPortraitReverse = false;
boolean hasLandscape = false;
boolean hasLandscapeReverse = false;

// update orientation modes that get exposed
// Store the given orientation modes.
orientationModes = modes;

// Fetch the activity to apply orientation modes to.
Activity activity = getActivity();
if (activity == null) {
return;
}

// Convert given Titanium orientation modes to an Android orientation identifier.
if (modes != null) {
// look through orientation modes and determine what has been set
for (int i = 0; i < orientationModes.length; i++) {
Expand Down Expand Up @@ -97,50 +104,28 @@ public void setOrientationModes(int[] modes)
} else if ((hasPortrait || hasPortraitReverse) && (hasLandscape || hasLandscapeReverse)) {
activityOrientationMode = ActivityInfo.SCREEN_ORIENTATION_SENSOR;
} else if (hasPortrait && hasPortraitReverse) {
//activityOrientationMode = ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT;

// unable to use constant until sdk lvl 9, use constant value instead
// if sdk level is less than 9, set as regular portrait
if (Build.VERSION.SDK_INT >= 9) {
activityOrientationMode = 7;
} else {
activityOrientationMode = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
}
activityOrientationMode = ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT;
} else if (hasLandscape && hasLandscapeReverse) {
//activityOrientationMode = ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE;

// unable to use constant until sdk lvl 9, use constant value instead
// if sdk level is less than 9, set as regular landscape
if (Build.VERSION.SDK_INT >= 9) {
activityOrientationMode = 6;
} else {
activityOrientationMode = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
}
activityOrientationMode = ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE;
} else if (hasPortrait) {
activityOrientationMode = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
} else if (hasPortraitReverse && Build.VERSION.SDK_INT >= 9) {
activityOrientationMode = 9;
} else if (hasPortraitReverse) {
activityOrientationMode = ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT;
} else if (hasLandscape) {
activityOrientationMode = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
} else if (hasLandscapeReverse && Build.VERSION.SDK_INT >= 9) {
activityOrientationMode = 8;
} else if (hasLandscapeReverse) {
activityOrientationMode = ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE;
}
} else if (activity instanceof TiBaseActivity) {
activityOrientationMode = ((TiBaseActivity) activity).getOriginalOrientationMode();
}

Activity activity = getActivity();
if (activity != null) {
if (activityOrientationMode != -1) {
activity.setRequestedOrientation(activityOrientationMode);
} else {
activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
}
}
} else {
Activity activity = getActivity();
if (activity != null) {
if (activity instanceof TiBaseActivity) {
activity.setRequestedOrientation(((TiBaseActivity) activity).getOriginalOrientationMode());
}
}
// Attempt to change the activity's orientation setting.
// Note: A semi-transparent activity cannot be assigned a fixed orientation. Will throw an exception.
try {
activity.setRequestedOrientation(activityOrientationMode);
} catch (Exception ex) {
Log.e(TAG, ex.getMessage());
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -322,15 +322,22 @@ public void setLeftNavButton(Object button)
public void setOrientationModes(int[] modes)
// clang-format on
{
int activityOrientationMode = -1;
int activityOrientationMode = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
boolean hasPortrait = false;
boolean hasPortraitReverse = false;
boolean hasLandscape = false;
boolean hasLandscapeReverse = false;

// update orientation modes that get exposed
// Store the given orientation modes.
orientationModes = modes;

// Fetch the activity to apply orientation modes to.
Activity activity = getActivity();
if (activity == null) {
return;
}

// Convert given Titanium orientation modes to an Android orientation identifier.
if (modes != null) {
// look through orientation modes and determine what has been set
for (int i = 0; i < orientationModes.length; i++) {
Expand Down Expand Up @@ -365,52 +372,28 @@ public void setOrientationModes(int[] modes)
} else if ((hasPortrait || hasPortraitReverse) && (hasLandscape || hasLandscapeReverse)) {
activityOrientationMode = ActivityInfo.SCREEN_ORIENTATION_SENSOR;
} else if (hasPortrait && hasPortraitReverse) {
//activityOrientationMode = ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT;

// unable to use constant until sdk lvl 9, use constant value instead
// if sdk level is less than 9, set as regular portrait
if (Build.VERSION.SDK_INT >= 9) {
activityOrientationMode = 7;
} else {
activityOrientationMode = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
}
activityOrientationMode = ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT;
} else if (hasLandscape && hasLandscapeReverse) {
//activityOrientationMode = ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE;

// unable to use constant until sdk lvl 9, use constant value instead
// if sdk level is less than 9, set as regular landscape
if (Build.VERSION.SDK_INT >= 9) {
activityOrientationMode = 6;
} else {
activityOrientationMode = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
}
activityOrientationMode = ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE;
} else if (hasPortrait) {
activityOrientationMode = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
} else if (hasPortraitReverse && Build.VERSION.SDK_INT >= 9) {
activityOrientationMode = 9;
} else if (hasPortraitReverse) {
activityOrientationMode = ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT;
} else if (hasLandscape) {
activityOrientationMode = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
} else if (hasLandscapeReverse && Build.VERSION.SDK_INT >= 9) {
activityOrientationMode = 8;
} else if (hasLandscapeReverse) {
activityOrientationMode = ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE;
}
} else if (activity instanceof TiBaseActivity) {
activityOrientationMode = ((TiBaseActivity) activity).getOriginalOrientationMode();
}

Activity activity = getWindowActivity();

// Wait until the window activity is created before setting orientation modes.
if (activity != null && windowActivityCreated) {
if (activityOrientationMode != -1) {
activity.setRequestedOrientation(activityOrientationMode);
} else {
activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
}
}
} else {
Activity activity = getActivity();
if (activity != null) {
if (activity instanceof TiBaseActivity) {
activity.setRequestedOrientation(((TiBaseActivity) activity).getOriginalOrientationMode());
}
}
// Attempt to change the activity's orientation setting.
// Note: A semi-transparent activity cannot be assigned a fixed orientation. Will throw an exception.
try {
activity.setRequestedOrientation(activityOrientationMode);
} catch (Exception ex) {
Log.e(TAG, ex.getMessage());
}
}

Expand Down
38 changes: 38 additions & 0 deletions tests/Resources/ti.ui.window.addontest.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* Appcelerator Titanium Mobile
* Copyright (c) 2011-Present by Appcelerator, Inc. All Rights Reserved.
* Licensed under the terms of the Apache Public License
* Please see the LICENSE included with this distribution for details.
*/
/* eslint-env mocha */
/* global Ti */
/* eslint no-unused-expressions: "off" */
'use strict';

describe('Titanium.UI.Window', function () {
var win;

afterEach(function () {
if (win) {
win.close();
}
win = null;
});

// As of Android 8.0, the OS will throw an exception if you apply a fixed orientation to a translucent window.
// Verify that Titanium handles the issue and avoids a crash.
it.android('TIMOB-26157', function (finish) {
this.slow(1000);
this.timeout(5000);

win = Ti.UI.createWindow({
backgroundColor: 'rgba(0,0,255,128)',
opacity: 0.5,
orientationModes: [ Ti.UI.PORTRAIT ]
});
win.addEventListener('open', function () {
finish();
});
win.open();
});
});

0 comments on commit ef2912f

Please sign in to comment.