Started changes for Android 13

This commit is contained in:
Sylvain Berfini 2022-06-09 14:02:03 +02:00
parent ee5af2b462
commit 635c8e69c7
20 changed files with 170 additions and 23 deletions

View file

@ -2,7 +2,7 @@ job-android:
stage: build
tags: [ "docker-android" ]
image: gitlab.linphone.org:4567/bc/public/linphone-android/bc-dev-android:20210903_java11_android31
image: gitlab.linphone.org:4567/bc/public/linphone-android/bc-dev-android:20220609_android_33
before_script:
- if ! [ -z ${SCP_PRIVATE_KEY+x} ]; then eval $(ssh-agent -s); fi

View file

@ -84,11 +84,11 @@ project.tasks['preBuild'].dependsOn 'getGitVersion'
project.tasks['preBuild'].dependsOn 'linphoneSdkSource'
android {
compileSdkVersion 31
buildToolsVersion '31.0.0'
compileSdkVersion 33
buildToolsVersion '33.0.0'
defaultConfig {
minSdkVersion 23
targetSdkVersion 31
targetSdkVersion 33
versionCode appVersionCode
versionName "${project.version}"
applicationId getPackageName()
@ -228,7 +228,7 @@ dependencies {
implementation 'androidx.emoji:emoji-bundled:1.1.0'
// https://github.com/material-components/material-components-android/blob/master/LICENSE Apache v2.0
implementation 'com.google.android.material:material:1.6.0'
implementation 'com.google.android.material:material:1.6.1'
// https://github.com/google/flexbox-layout/blob/main/LICENSE Apache v2.0
implementation 'com.google.android.flexbox:flexbox:3.0.0'

View file

@ -1,7 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<!-- To be able to display contacts list & match calling/called numbers -->
<uses-permission android:name="android.permission.READ_CONTACTS" />
<!-- For in-app contact edition -->
<uses-permission android:name="android.permission.WRITE_CONTACTS" />
<!-- Helps filling phone number and country code in assistant -->
@ -10,17 +12,22 @@
<!-- Needed for auto start at boot and to ensure the service won't be killed by OS while in call -->
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<!-- Starting Android 13 we need to ask notification permission -->
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
<!-- Needed for full screen intent in incoming call notifications -->
<uses-permission android:name="android.permission.USE_FULL_SCREEN_INTENT" />
<!-- To vibrate when pressing DTMF keys on numpad -->
<!-- To vibrate when pressing DTMF keys on numpad & incoming calls -->
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<!-- Needed to attach file(s) in chat room fragment -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"
android:maxSdkVersion="32"/>
<!-- Needed to shared downloaded files if setting is on -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="28" />
<!-- Both permissions below are for contacts sync account -->
<!-- Both permissions below are for contacts sync account, needed to store presence in native contact if enabled -->
<uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />

View file

@ -59,6 +59,9 @@ class EchoCancellerCalibrationViewModel : ViewModel() {
EcCalibratorStatus.Failed -> {
Log.w("[Echo Canceller Calibration] Failed")
}
EcCalibratorStatus.InProgress -> {
Log.i("[Echo Canceller Calibration] In progress")
}
}
echoCalibrationTerminated.value = Event(true)
}

View file

@ -47,6 +47,7 @@ class RemoteProvisioningViewModel : ViewModel() {
ConfiguringState.Failed -> {
fetchSuccessfulEvent.value = Event(false)
}
else -> {}
}
}
}

View file

@ -100,6 +100,7 @@ class ImdnAdapter(
binding.textColor = R.color.red_color
binding.icon = R.drawable.chat_error
}
else -> {}
}
binding.executePendingBindings()
return binding.root

View file

@ -412,6 +412,7 @@ class ChatMessageContentData(
AudioDevice.Type.Headphones, AudioDevice.Type.Headset -> {
headphonesCard = device.id
}
else -> {}
}
}
}

View file

@ -19,6 +19,7 @@
*/
package org.linphone.activities.main.chat.fragments
import android.Manifest
import android.app.Activity
import android.app.Dialog
import android.content.Intent
@ -572,8 +573,8 @@ class DetailChatRoomFragment : MasterFragment<ChatRoomDetailFragmentBinding, Cha
Log.i("[Chat Room] Asking for READ_EXTERNAL_STORAGE and CAMERA permissions")
requestPermissions(
arrayOf(
android.Manifest.permission.READ_EXTERNAL_STORAGE,
android.Manifest.permission.CAMERA
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.CAMERA
),
0
)

View file

@ -467,6 +467,7 @@ class ChatMessageSendingViewModel(private val chatRoom: ChatRoom) : ViewModel()
AudioDevice.Type.Headphones, AudioDevice.Type.Headset -> {
headphonesCard = device.id
}
else -> {}
}
}
}

View file

@ -224,7 +224,7 @@ class DialerFragment : SecureFragment<DialerFragmentBinding>() {
Log.i("[Dialer] READ_PHONE_STATE permission has been granted")
coreContext.initPhoneStateListener()
}
checkTelecomManagerPermissions()
checkPermissions()
} else if (requestCode == 1) {
var allGranted = true
for (result in grantResults) {
@ -238,22 +238,26 @@ class DialerFragment : SecureFragment<DialerFragmentBinding>() {
} else {
Log.w("[Dialer] Telecom Manager permission have been denied (at least one of them)")
}
} else if (requestCode == 2) {
if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Log.i("[Dialer] POST_NOTIFICATIONS permission has been granted")
}
checkTelecomManagerPermissions()
}
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
}
private fun checkPermissions() {
checkReadPhoneStatePermission()
if (Version.sdkAboveOrEqual(Version.API26_O_80) && PermissionHelper.get().hasReadPhoneStatePermission()) {
// Don't check the following the previous permission is being asked
checkTelecomManagerPermissions()
}
}
private fun checkReadPhoneStatePermission() {
if (!PermissionHelper.get().hasReadPhoneStatePermission()) {
Log.i("[Dialer] Asking for READ_PHONE_STATE permission")
requestPermissions(arrayOf(Manifest.permission.READ_PHONE_STATE), 0)
} else if (!PermissionHelper.get().hasPostNotificationsPermission()) {
// Don't check the following the previous permission is being asked
Log.i("[Dialer] Asking for POST_NOTIFICATIONS permission")
Compatibility.requestPostNotificationsPermission(this, 2)
} else if (Version.sdkAboveOrEqual(Version.API26_O_80)) {
// Don't check the following the previous permissions are being asked
checkTelecomManagerPermissions()
}
}

View file

@ -181,6 +181,7 @@ class RecordingData(val path: String, private val recordingListener: RecordingLi
AudioDevice.Type.Headphones, AudioDevice.Type.Headset -> {
headphonesCard = device.id
}
else -> {}
}
}
}

View file

@ -19,6 +19,7 @@
*/
package org.linphone.activities.voip.fragments
import android.Manifest
import android.app.Activity
import android.content.Intent
import android.content.pm.PackageManager
@ -88,8 +89,8 @@ class ChatFragment : GenericFragment<VoipChatFragmentBinding>() {
Log.i("[Chat] Asking for READ_EXTERNAL_STORAGE and CAMERA permissions")
requestPermissions(
arrayOf(
android.Manifest.permission.READ_EXTERNAL_STORAGE,
android.Manifest.permission.CAMERA
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.CAMERA
),
0
)

View file

@ -0,0 +1,42 @@
/*
* Copyright (c) 2010-2022 Belledonne Communications SARL.
*
* This file is part of linphone-android
* (see https://www.linphone.org).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.linphone.compatibility
import android.annotation.TargetApi
import android.content.Context
import androidx.fragment.app.Fragment
@TargetApi(33)
class Api33Compatibility {
companion object {
fun requestPostNotificationsPermission(fragment: Fragment, code: Int) {
fragment.requestPermissions(
arrayOf(
"android.permission.POST_NOTIFICATIONS"
),
code
)
}
fun hasPostNotificationsPermission(context: Context): Boolean {
return Compatibility.hasPermission(context, "android.permission.POST_NOTIFICATIONS")
}
}
}

View file

@ -95,6 +95,18 @@ class Compatibility {
}
}
fun requestPostNotificationsPermission(fragment: Fragment, code: Int) {
if (Version.sdkAboveOrEqual(Version.API33_ANDROID_13_TIRAMISU)) {
Api33Compatibility.requestPostNotificationsPermission(fragment, code)
}
}
fun hasPostNotificationsPermission(context: Context): Boolean {
return if (Version.sdkAboveOrEqual(Version.API33_ANDROID_13_TIRAMISU)) {
Api33Compatibility.hasPostNotificationsPermission(context)
} else true
}
fun getDeviceName(context: Context): String {
return when (Version.sdkAboveOrEqual(Version.API25_NOUGAT_71)) {
true -> Api25Compatibility.getDeviceName(context)

View file

@ -281,6 +281,11 @@ class NotificationsManager(private val context: Context) {
}
private fun notify(id: Int, notification: Notification, tag: String? = null) {
if (!PermissionHelper.get().hasPostNotificationsPermission()) {
Log.w("[Notifications Manager] Can't notify [$id] with tag [$tag], POST_NOTIFICATIONS permission isn't granted!")
return
}
Log.i("[Notifications Manager] Notifying [$id] with tag [$tag]")
notificationManager.notify(tag, id, notification)
}

View file

@ -52,6 +52,7 @@ class TelecomConnectionService : ConnectionService() {
Call.State.Error -> onCallError(call)
Call.State.End, Call.State.Released -> onCallEnded(call)
Call.State.Connected -> onCallConnected(call)
else -> {}
}
}

View file

@ -79,4 +79,8 @@ class PermissionHelper private constructor(private val context: Context) {
fun hasBluetoothConnectPermission(): Boolean {
return Compatibility.hasBluetoothConnectPermission(context)
}
fun hasPostNotificationsPermission(): Boolean {
return Compatibility.hasPostNotificationsPermission(context)
}
}

View file

@ -13,7 +13,7 @@ buildscript {
dependencies {
classpath 'com.android.tools.build:gradle:7.2.1'
classpath 'com.google.gms:google-services:4.3.10'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.21"
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.7.0"
classpath "org.jlleitschuh.gradle:ktlint-gradle:10.1.0"
classpath 'com.google.firebase:firebase-crashlytics-gradle:2.9.0'
}

View file

@ -0,0 +1,62 @@
FROM debian:stretch
MAINTAINER Sylvain BERFINI <sylvain.berfini@belledonne-communications.com>
# Configure locale
RUN apt-get update && \
apt-get install -y locales && \
apt-get clean && \
echo "en_US.UTF-8 UTF-8" > /etc/locale.gen && \
locale-gen
ENV LANG='en_US.UTF-8' LANGUAGE='en_US:en' LC_ALL='en_US.UTF-8'
ENV SHELL=/bin/bash
# Define environment
ENV ANDROID_SDK 25.2.5
ENV ANDROID_HOME /opt/android-sdk-linux
ENV ANDROID_NDK_HOME /opt/android-sdk-linux/ndk
# Backports required for JDK 11
RUN echo "deb http://deb.debian.org/debian stretch-backports main" > /etc/apt/sources.list.d/backports.list
# Install common general tools
RUN apt-get update && \
apt-get install -y curl nano sudo unzip vim wget rsync ssh git openjdk-8-jdk-headless && \
apt-get -t stretch-backports install -y openjdk-11-jdk-headless && \
apt-get clean
# Get the Android tools
RUN wget https://dl.google.com/android/repository/tools_r$ANDROID_SDK-linux.zip && \
unzip tools_r$ANDROID_SDK-linux.zip -d $ANDROID_HOME && \
rm -f tools_r$ANDROID_SDK-linux.zip
# Get latest Android command line tools, otherwise won't work with JDK 11
RUN mkdir -p $ANDROID_HOME/cmdline-tools/latest
RUN wget https://dl.google.com/android/repository/commandlinetools-linux-7583922_latest.zip && \
unzip commandlinetools-linux-7583922_latest.zip && \
cp -R ./cmdline-tools/* $ANDROID_HOME/cmdline-tools/latest/ && \
rm -rf ./cmdline-tools && \
rm -rf commandlinetools-linux-7583922_latest.zip
# Update path to include all Android SDK tools
ENV PATH $ANDROID_HOME/cmdline-tools/latest/bin:$ANDROID_HOME/tools:$ANDROID_HOME/tools/bin:$ANDROID_HOME/platform-tools:ANDROID_NDK_HOME:$PATH
# Test
RUN $ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager --list --verbose --sdk_root=$ANDROID_HOME
# Get the Android SDK
RUN echo "y" | $ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager "platforms;android-33" "build-tools;33.0.0" "extras;android;m2repository" "extras;google;m2repository" "platform-tools" "tools" "ndk;21.3.6528147" --sdk_root=$ANDROID_HOME
# Accept Android SDK licenses
RUN yes | $ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager --licenses --sdk_root=$ANDROID_HOME
# Configure user bc
RUN useradd -ms /bin/bash bc && \
echo 'bc:cotcot' | chpasswd && \
echo 'bc ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers
USER bc
WORKDIR /home/bc
ENV PS1='\[\e[34m\]\u@bc-dev-android>\[\e[0m\] '
CMD bash

View file

@ -1,6 +1,6 @@
#Thu Feb 03 11:43:32 CET 2022
distributionBase=GRADLE_USER_HOME
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-bin.zip
distributionPath=wrapper/dists
zipStorePath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME