Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ android {
ndkVersion project.ext.tiNdkVersion
defaultConfig {
applicationId 'com.titanium.test'
minSdkVersion 21
minSdkVersion 23
targetSdkVersion 35
versionCode 1
versionName '1.0'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -661,22 +661,20 @@ public void stopService(IntentProxy intentProxy)
@Kroll.method
public boolean hasPermission(Object permissionObject)
{
if (Build.VERSION.SDK_INT >= 23) {
ArrayList<String> permissions = new ArrayList<>();
if (permissionObject instanceof String) {
permissions.add((String) permissionObject);
} else if (permissionObject instanceof Object[]) {
for (Object permission : (Object[]) permissionObject) {
if (permission instanceof String) {
permissions.add((String) permission);
}
ArrayList<String> permissions = new ArrayList<>();
if (permissionObject instanceof String) {
permissions.add((String) permissionObject);
} else if (permissionObject instanceof Object[]) {
for (Object permission : (Object[]) permissionObject) {
if (permission instanceof String) {
permissions.add((String) permission);
}
}
Activity currentActivity = TiApplication.getInstance().getCurrentActivity();
for (String permission : permissions) {
if (currentActivity.checkSelfPermission(permission) != PackageManager.PERMISSION_GRANTED) {
return false;
}
}
Activity currentActivity = TiApplication.getInstance().getCurrentActivity();
for (String permission : permissions) {
if (currentActivity.checkSelfPermission(permission) != PackageManager.PERMISSION_GRANTED) {
return false;
}
}
return true;
Expand All @@ -690,31 +688,29 @@ public KrollPromise<KrollDict> requestPermissions(final Object permissionObject,
// to fire the callback when we resolve/reject?
final KrollObject callbackThisObject = getKrollObject();
return KrollPromise.create((promise) -> {
if (Build.VERSION.SDK_INT >= 23) {
List<String> permissions = new ArrayList<String>();
if (permissionObject instanceof String) {
permissions.add((String) permissionObject);
} else if (permissionObject instanceof Object[]) {
for (Object permission : (Object[]) permissionObject) {
if (permission instanceof String) {
permissions.add((String) permission);
}
}
}
Activity currentActivity = TiApplication.getInstance().getCurrentActivity();
List<String> filteredPermissions = new ArrayList<String>();
for (String permission : permissions) {
if (currentActivity.checkSelfPermission(permission) == PackageManager.PERMISSION_GRANTED) {
continue;
List<String> permissions = new ArrayList<String>();
if (permissionObject instanceof String) {
permissions.add((String) permissionObject);
} else if (permissionObject instanceof Object[]) {
for (Object permission : (Object[]) permissionObject) {
if (permission instanceof String) {
permissions.add((String) permission);
}
filteredPermissions.add(permission);
}
if (filteredPermissions.size() > 0) {
TiBaseActivity.registerPermissionRequestCallback(REQUEST_CODE, permissionCallback,
callbackThisObject, promise);
currentActivity.requestPermissions(filteredPermissions.toArray(new String[0]), REQUEST_CODE);
return;
}
Activity currentActivity = TiApplication.getInstance().getCurrentActivity();
List<String> filteredPermissions = new ArrayList<String>();
for (String permission : permissions) {
if (currentActivity.checkSelfPermission(permission) == PackageManager.PERMISSION_GRANTED) {
continue;
}
filteredPermissions.add(permission);
}
if (filteredPermissions.size() > 0) {
TiBaseActivity.registerPermissionRequestCallback(REQUEST_CODE, permissionCallback,
callbackThisObject, promise);
currentActivity.requestPermissions(filteredPermissions.toArray(new String[0]), REQUEST_CODE);
return;
}
// FIXME: If we're not on API level 23+, shouldn't we reject/error?
KrollDict response = new KrollDict();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,7 @@ private ActionMode.Callback onWrap(ActionMode.Callback callback)
}

// Wrap the given callback used to override context menu handling.
if ((Build.VERSION.SDK_INT >= 23) && (callback instanceof ActionMode.Callback2)) {
if (callback instanceof ActionMode.Callback2) {
callback = new ActionModeCallback2Wrapper((ActionMode.Callback2) callback, excludeMenuIdSet);
} else {
callback = new ActionModeCallbackWrapper(callback, excludeMenuIdSet);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,11 +127,7 @@ public TiUITimePicker(@NonNull PickerProxy proxy)
View amView = timePicker.findViewById(id_am);
View pmView = timePicker.findViewById(id_pm);
View.OnClickListener listener = (View v) -> {
if (Build.VERSION.SDK_INT >= 23) {
timePicker.setHour((timePicker.getHour() + 12) % 24);
} else {
timePicker.setCurrentHour((timePicker.getCurrentHour() + 12) % 24);
}
timePicker.setHour((timePicker.getHour() + 12) % 24);
};
if (amView != null) {
amView.setOnClickListener(listener);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,48 +84,46 @@ public void onGeolocationPermissionsShowPrompt(
// Prompt end-user for FINE location permission on Android 6.0 and higher if needed.
// Note: As of Android 12, we must also request the COARSE permission (will fail without it),
// but ignore COARSE permission since WebView location access requires FINE.
if (Build.VERSION.SDK_INT >= 23) {
int permissionResult = activity.checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION);
if (permissionResult != PackageManager.PERMISSION_GRANTED) {
if (activity.shouldShowRequestPermissionRationale(Manifest.permission.ACCESS_FINE_LOCATION)) {
// System won't prompt for permission since user already denied it. So, immediately fail it.
callback.invoke(origin, false, false);
} else {
// Prompt end-user for permission.
TiBaseActivity.OnRequestPermissionsResultCallback activityCallback;
activityCallback = new TiBaseActivity.OnRequestPermissionsResultCallback() {
@Override
public void onRequestPermissionsResult(
@NonNull TiBaseActivity activity, int requestCode,
@NonNull String[] permissions, @NonNull int[] grantResults)
{
// Unregister this callback.
TiBaseActivity.unregisterPermissionRequestCallback(TiC.PERMISSION_CODE_LOCATION);

// Determine if FINE location permission was granted. (Ignore COARSE permission.)
boolean granted = false;
if (permissions.length == grantResults.length) {
for (int index = 0; index < permissions.length; index++) {
if (Manifest.permission.ACCESS_FINE_LOCATION.equals(permissions[index])) {
granted = (grantResults[index] == PackageManager.PERMISSION_GRANTED);
break;
}
int permissionResult = activity.checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION);
if (permissionResult != PackageManager.PERMISSION_GRANTED) {
if (activity.shouldShowRequestPermissionRationale(Manifest.permission.ACCESS_FINE_LOCATION)) {
// System won't prompt for permission since user already denied it. So, immediately fail it.
callback.invoke(origin, false, false);
} else {
// Prompt end-user for permission.
TiBaseActivity.OnRequestPermissionsResultCallback activityCallback;
activityCallback = new TiBaseActivity.OnRequestPermissionsResultCallback() {
@Override
public void onRequestPermissionsResult(
@NonNull TiBaseActivity activity, int requestCode,
@NonNull String[] permissions, @NonNull int[] grantResults)
{
// Unregister this callback.
TiBaseActivity.unregisterPermissionRequestCallback(TiC.PERMISSION_CODE_LOCATION);

// Determine if FINE location permission was granted. (Ignore COARSE permission.)
boolean granted = false;
if (permissions.length == grantResults.length) {
for (int index = 0; index < permissions.length; index++) {
if (Manifest.permission.ACCESS_FINE_LOCATION.equals(permissions[index])) {
granted = (grantResults[index] == PackageManager.PERMISSION_GRANTED);
break;
}
}

// Notify WebView whether or not location access was granted.
callback.invoke(origin, granted, false);
}
};
TiBaseActivity.registerPermissionRequestCallback(TiC.PERMISSION_CODE_LOCATION, activityCallback);
String[] permissions = new String[] {
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION
};
activity.requestPermissions(permissions, TiC.PERMISSION_CODE_LOCATION);
}
return;

// Notify WebView whether or not location access was granted.
callback.invoke(origin, granted, false);
}
};
TiBaseActivity.registerPermissionRequestCallback(TiC.PERMISSION_CODE_LOCATION, activityCallback);
String[] permissions = new String[] {
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION
};
activity.requestPermissions(permissions, TiC.PERMISSION_CODE_LOCATION);
}
return;
}

// Notify WebView that location access is granted.
Expand Down Expand Up @@ -161,76 +159,74 @@ public void onPermissionRequest(final PermissionRequest request)
}

// Prompt end-user for permission on Android 6.0 and higher if needed.
if (Build.VERSION.SDK_INT >= 23) {
// Determine if we need to request for any permissions.
boolean isAudioRecordingPermissionRequired = false;
boolean isCameraPermissionRequired = false;
for (String nextName : resourceNames) {
if (PermissionRequest.RESOURCE_AUDIO_CAPTURE.equals(nextName)) {
int result = tiActivity.checkSelfPermission(Manifest.permission.RECORD_AUDIO);
isAudioRecordingPermissionRequired = (result != PackageManager.PERMISSION_GRANTED);
} else if (PermissionRequest.RESOURCE_VIDEO_CAPTURE.equals(nextName)) {
int result = tiActivity.checkSelfPermission(Manifest.permission.CAMERA);
isCameraPermissionRequired = (result != PackageManager.PERMISSION_GRANTED);
}
// Determine if we need to request for any permissions.
boolean isAudioRecordingPermissionRequired = false;
boolean isCameraPermissionRequired = false;
for (String nextName : resourceNames) {
if (PermissionRequest.RESOURCE_AUDIO_CAPTURE.equals(nextName)) {
int result = tiActivity.checkSelfPermission(Manifest.permission.RECORD_AUDIO);
isAudioRecordingPermissionRequired = (result != PackageManager.PERMISSION_GRANTED);
} else if (PermissionRequest.RESOURCE_VIDEO_CAPTURE.equals(nextName)) {
int result = tiActivity.checkSelfPermission(Manifest.permission.CAMERA);
isCameraPermissionRequired = (result != PackageManager.PERMISSION_GRANTED);
}
}

// Request permissions from end-user if needed.
if (isAudioRecordingPermissionRequired || isCameraPermissionRequired) {
ArrayList<String> permissionNameList = new ArrayList<>();
if (isAudioRecordingPermissionRequired) {
permissionNameList.add(Manifest.permission.RECORD_AUDIO);
}
if (isCameraPermissionRequired) {
permissionNameList.add(Manifest.permission.CAMERA);
}
TiBaseActivity.OnRequestPermissionsResultCallback callback;
callback = new TiBaseActivity.OnRequestPermissionsResultCallback() {
@Override
public void onRequestPermissionsResult(
@NonNull TiBaseActivity activity, int requestCode,
@NonNull String[] permissions, @NonNull int[] grantResults)
{
// Unregister this callback.
TiBaseActivity.unregisterPermissionRequestCallback(TiC.PERMISSION_CODE_CAMERA);

// Create a new resource name list with all granted permissions.
ArrayList<String> resourceNameList = new ArrayList<>();
for (String resourceName : request.getResources()) {
String permissionName = null;
if (PermissionRequest.RESOURCE_AUDIO_CAPTURE.equals(resourceName)) {
permissionName = Manifest.permission.RECORD_AUDIO;
} else if (PermissionRequest.RESOURCE_VIDEO_CAPTURE.equals(resourceName)) {
permissionName = Manifest.permission.CAMERA;
}
if (permissionName != null) {
// Check if resource was granted permission. If so, then add it to the list.
for (int index = 0; index < permissions.length; index++) {
if (permissionName.equals(permissions[index])) {
if (grantResults[index] == PackageManager.PERMISSION_GRANTED) {
resourceNameList.add(resourceName);
break;
}
// Request permissions from end-user if needed.
if (isAudioRecordingPermissionRequired || isCameraPermissionRequired) {
ArrayList<String> permissionNameList = new ArrayList<>();
if (isAudioRecordingPermissionRequired) {
permissionNameList.add(Manifest.permission.RECORD_AUDIO);
}
if (isCameraPermissionRequired) {
permissionNameList.add(Manifest.permission.CAMERA);
}
TiBaseActivity.OnRequestPermissionsResultCallback callback;
callback = new TiBaseActivity.OnRequestPermissionsResultCallback() {
@Override
public void onRequestPermissionsResult(
@NonNull TiBaseActivity activity, int requestCode,
@NonNull String[] permissions, @NonNull int[] grantResults)
{
// Unregister this callback.
TiBaseActivity.unregisterPermissionRequestCallback(TiC.PERMISSION_CODE_CAMERA);

// Create a new resource name list with all granted permissions.
ArrayList<String> resourceNameList = new ArrayList<>();
for (String resourceName : request.getResources()) {
String permissionName = null;
if (PermissionRequest.RESOURCE_AUDIO_CAPTURE.equals(resourceName)) {
permissionName = Manifest.permission.RECORD_AUDIO;
} else if (PermissionRequest.RESOURCE_VIDEO_CAPTURE.equals(resourceName)) {
permissionName = Manifest.permission.CAMERA;
}
if (permissionName != null) {
// Check if resource was granted permission. If so, then add it to the list.
for (int index = 0; index < permissions.length; index++) {
if (permissionName.equals(permissions[index])) {
if (grantResults[index] == PackageManager.PERMISSION_GRANTED) {
resourceNameList.add(resourceName);
break;
}
}
} else {
// This resource does not require permission. Add it to the granted list.
resourceNameList.add(resourceName);
}
}

// Notify WebView if which resources were granted permission.
if (resourceNameList.isEmpty()) {
request.deny();
} else {
request.grant(resourceNameList.toArray(new String[0]));
// This resource does not require permission. Add it to the granted list.
resourceNameList.add(resourceName);
}
}
};
TiBaseActivity.registerPermissionRequestCallback(TiC.PERMISSION_CODE_CAMERA, callback);
tiActivity.requestPermissions(permissionNameList.toArray(new String[0]), TiC.PERMISSION_CODE_CAMERA);
return;
}

// Notify WebView if which resources were granted permission.
if (resourceNameList.isEmpty()) {
request.deny();
} else {
request.grant(resourceNameList.toArray(new String[0]));
}
}
};
TiBaseActivity.registerPermissionRequestCallback(TiC.PERMISSION_CODE_CAMERA, callback);
tiActivity.requestPermissions(permissionNameList.toArray(new String[0]), TiC.PERMISSION_CODE_CAMERA);
return;
}

// Grant permission to all resources.
Expand Down Expand Up @@ -422,7 +418,7 @@ public boolean onShowFileChooser(

// Prompt the end-user for camera permission if required.
// Note: We only need external storage permission on OS versions older than Android 10.
if (chooserParams.isCaptureEnabled() && (Build.VERSION.SDK_INT >= 23)) {
if (chooserParams.isCaptureEnabled()) {
int permissionResult = activity.checkSelfPermission(Manifest.permission.CAMERA);
boolean isCameraPermissionRequired = (permissionResult != PackageManager.PERMISSION_GRANTED);
boolean isStoragePermissionRequired = (Build.VERSION.SDK_INT < 29);
Expand Down
2 changes: 1 addition & 1 deletion android/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
"mode": "release",
"integrity": "sha512-A0tV+fYtkpKfIF5roRTCFPtdULMFygmfWlEuuHOBjC3q4rz/mKnAsJTYBlqayC/4oYEWehj867Oh1o6vy26XHQ=="
},
"minSDKVersion": "21",
"minSDKVersion": "23",
"compileSDKVersion": "35",
"vendorDependencies": {
"android sdk": ">=23.x <=35.x",
Expand Down
2 changes: 1 addition & 1 deletion android/templates/module/generated/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ android {
namespace '<%- moduleId %>'
ndkVersion '28.1.13356709'
defaultConfig {
minSdkVersion 21
minSdkVersion 23
targetSdkVersion <%- compileSdkVersion %>
versionName '<%- moduleVersion %>'

Expand Down
2 changes: 1 addition & 1 deletion android/titanium/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ android {
namespace 'org.appcelerator.titanium'
defaultConfig {
compileSdk 35
minSdkVersion 21
minSdkVersion 23
targetSdkVersion 35
versionName tiBuildVersionString
versionCode tiBuildVersionCode
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -402,17 +402,7 @@ private void update()
// Fetch the currently applied insets and update safe-area.
// Note: Google's internal code comments states that getWindowVisibleDisplayFrame() is "broken".
// It's proven to work for us, but let's avoid this API in case of any unknown edge cases.
if (Build.VERSION.SDK_INT >= 23) {
updateUsing(rootView.getRootWindowInsets());
} else {
Rect rect = new Rect(rootView.getLeft(), rootView.getTop(), rootView.getRight(), rootView.getBottom());
rootView.getWindowVisibleDisplayFrame(rect);
this.insetLeft = Math.max(rect.left - rootView.getLeft(), 0);
this.insetTop = Math.max(rect.top - rootView.getTop(), 0);
this.insetRight = Math.max(rootView.getRight() - rect.right, 0);
this.insetBottom = Math.max(rootView.getBottom() - rect.bottom, 0);
updateUsingCachedInsets();
}
updateUsing(rootView.getRootWindowInsets());
}

/**
Expand Down
Loading