diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d64626d --- /dev/null +++ b/.gitignore @@ -0,0 +1,22 @@ +*.iml +.cursor/ +.gradle/ +/local.properties +/.idea/ +.DS_Store +/build/ +/captures/ +.externalNativeBuild/ +.cxx/ +app/build/ +modules/*/build/ +modules/*/.git/ +*.apk +*.ap_ +*.dex +*.class +bin/ +gen/ +out/ +tools/messaging_*.png +tools/stitch-*.txt diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..f117773 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,89 @@ +plugins { + id 'com.android.application' +} + +android { + namespace 'com.android.messaging' + compileSdk 35 + + defaultConfig { + applicationId 'com.android.messaging' + minSdk 33 + targetSdk 34 + versionCode 10001040 + versionName '1.0.001' + vectorDrawables.useSupportLibrary true + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_17 + targetCompatibility JavaVersion.VERSION_17 + } + + buildTypes { + release { + minifyEnabled true + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), + rootProject.file('proguard-release.flags'), + rootProject.file('proguard.flags') + } + debug { + minifyEnabled false + } + } + + lint { + abortOnError false + } + + sourceSets { + main { + manifest.srcFile 'src/main/AndroidManifest.xml' + java.srcDirs = ['src/main/java'] + res.srcDirs = ['src/main/res'] + assets.srcDirs = ['src/main/assets'] + } + } +} + +dependencies { + implementation project(':modules:colorpicker') + implementation project(':modules:chips') + implementation project(':modules:photoviewer') + implementation project(':modules:vcard') + + implementation 'androidx.activity:activity:1.9.3' + implementation 'androidx.annotation:annotation:1.8.2' + implementation 'androidx.appcompat:appcompat:1.7.0' + implementation 'androidx.collection:collection:1.4.4' + implementation 'androidx.core:core:1.15.0' + implementation 'androidx.exifinterface:exifinterface:1.3.7' + implementation 'androidx.fragment:fragment:1.8.5' + implementation 'androidx.media:media:1.7.0' + implementation 'androidx.palette:palette:1.0.0' + implementation 'androidx.preference:preference:1.2.1' + implementation 'androidx.recyclerview:recyclerview:1.3.2' + implementation 'androidx.viewpager:viewpager:1.0.0' + implementation 'com.google.android.material:material:1.12.0' + implementation 'com.google.guava:guava:33.3.1-android' + implementation 'com.googlecode.libphonenumber:libphonenumber:8.13.50' +} + +def messagingAvdSerial = rootProject.findProperty('messaging.avd.serial') ?: 'emulator-5556' +def adbExecutable = new File(android.sdkDirectory, 'platform-tools/adb.exe') + +tasks.register('installMessaging', Exec) { + group = 'install' + description = "Install debug APK on ${messagingAvdSerial} only" + dependsOn 'assembleDebug' + def apk = layout.buildDirectory.file('outputs/apk/debug/app-debug.apk').get().asFile + commandLine adbExecutable.absolutePath, '-s', messagingAvdSerial, 'install', '-r', apk.absolutePath +} + +tasks.register('launchMessaging', Exec) { + group = 'install' + description = "Launch Messaging on ${messagingAvdSerial}" + dependsOn 'installMessaging' + commandLine adbExecutable.absolutePath, '-s', messagingAvdSerial, 'shell', 'am', 'start', + '-n', 'com.android.messaging/.ui.conversationlist.ConversationListActivity' +} diff --git a/AndroidManifest.xml b/app/src/main/AndroidManifest.xml similarity index 99% rename from AndroidManifest.xml rename to app/src/main/AndroidManifest.xml index c6ba856..a789ef2 100644 --- a/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -19,10 +19,6 @@ package="com.android.messaging" android:installLocation="internalOnly"> - - diff --git a/assets/licenses.html b/app/src/main/assets/licenses.html similarity index 100% rename from assets/licenses.html rename to app/src/main/assets/licenses.html diff --git a/src/android/support/v7/mms/ApnException.java b/app/src/main/java/android/support/v7/mms/ApnException.java similarity index 100% rename from src/android/support/v7/mms/ApnException.java rename to app/src/main/java/android/support/v7/mms/ApnException.java diff --git a/src/android/support/v7/mms/ApnSettingsLoader.java b/app/src/main/java/android/support/v7/mms/ApnSettingsLoader.java similarity index 100% rename from src/android/support/v7/mms/ApnSettingsLoader.java rename to app/src/main/java/android/support/v7/mms/ApnSettingsLoader.java diff --git a/src/android/support/v7/mms/ApnsXmlParser.java b/app/src/main/java/android/support/v7/mms/ApnsXmlParser.java similarity index 100% rename from src/android/support/v7/mms/ApnsXmlParser.java rename to app/src/main/java/android/support/v7/mms/ApnsXmlParser.java diff --git a/src/android/support/v7/mms/CarrierConfigValuesLoader.java b/app/src/main/java/android/support/v7/mms/CarrierConfigValuesLoader.java similarity index 100% rename from src/android/support/v7/mms/CarrierConfigValuesLoader.java rename to app/src/main/java/android/support/v7/mms/CarrierConfigValuesLoader.java diff --git a/src/android/support/v7/mms/CarrierConfigXmlParser.java b/app/src/main/java/android/support/v7/mms/CarrierConfigXmlParser.java similarity index 100% rename from src/android/support/v7/mms/CarrierConfigXmlParser.java rename to app/src/main/java/android/support/v7/mms/CarrierConfigXmlParser.java diff --git a/src/android/support/v7/mms/DefaultApnSettingsLoader.java b/app/src/main/java/android/support/v7/mms/DefaultApnSettingsLoader.java similarity index 100% rename from src/android/support/v7/mms/DefaultApnSettingsLoader.java rename to app/src/main/java/android/support/v7/mms/DefaultApnSettingsLoader.java diff --git a/src/android/support/v7/mms/DefaultCarrierConfigValuesLoader.java b/app/src/main/java/android/support/v7/mms/DefaultCarrierConfigValuesLoader.java similarity index 100% rename from src/android/support/v7/mms/DefaultCarrierConfigValuesLoader.java rename to app/src/main/java/android/support/v7/mms/DefaultCarrierConfigValuesLoader.java diff --git a/src/android/support/v7/mms/DefaultUserAgentInfoLoader.java b/app/src/main/java/android/support/v7/mms/DefaultUserAgentInfoLoader.java similarity index 100% rename from src/android/support/v7/mms/DefaultUserAgentInfoLoader.java rename to app/src/main/java/android/support/v7/mms/DefaultUserAgentInfoLoader.java diff --git a/src/android/support/v7/mms/DownloadRequest.java b/app/src/main/java/android/support/v7/mms/DownloadRequest.java similarity index 100% rename from src/android/support/v7/mms/DownloadRequest.java rename to app/src/main/java/android/support/v7/mms/DownloadRequest.java diff --git a/src/android/support/v7/mms/MmsHttpClient.java b/app/src/main/java/android/support/v7/mms/MmsHttpClient.java similarity index 100% rename from src/android/support/v7/mms/MmsHttpClient.java rename to app/src/main/java/android/support/v7/mms/MmsHttpClient.java diff --git a/src/android/support/v7/mms/MmsHttpException.java b/app/src/main/java/android/support/v7/mms/MmsHttpException.java similarity index 100% rename from src/android/support/v7/mms/MmsHttpException.java rename to app/src/main/java/android/support/v7/mms/MmsHttpException.java diff --git a/src/android/support/v7/mms/MmsManager.java b/app/src/main/java/android/support/v7/mms/MmsManager.java similarity index 100% rename from src/android/support/v7/mms/MmsManager.java rename to app/src/main/java/android/support/v7/mms/MmsManager.java diff --git a/src/android/support/v7/mms/MmsNetworkException.java b/app/src/main/java/android/support/v7/mms/MmsNetworkException.java similarity index 100% rename from src/android/support/v7/mms/MmsNetworkException.java rename to app/src/main/java/android/support/v7/mms/MmsNetworkException.java diff --git a/src/android/support/v7/mms/MmsNetworkManager.java b/app/src/main/java/android/support/v7/mms/MmsNetworkManager.java similarity index 100% rename from src/android/support/v7/mms/MmsNetworkManager.java rename to app/src/main/java/android/support/v7/mms/MmsNetworkManager.java diff --git a/src/android/support/v7/mms/MmsRequest.java b/app/src/main/java/android/support/v7/mms/MmsRequest.java similarity index 100% rename from src/android/support/v7/mms/MmsRequest.java rename to app/src/main/java/android/support/v7/mms/MmsRequest.java diff --git a/src/android/support/v7/mms/MmsService.java b/app/src/main/java/android/support/v7/mms/MmsService.java similarity index 100% rename from src/android/support/v7/mms/MmsService.java rename to app/src/main/java/android/support/v7/mms/MmsService.java diff --git a/src/android/support/v7/mms/MmsXmlResourceParser.java b/app/src/main/java/android/support/v7/mms/MmsXmlResourceParser.java similarity index 100% rename from src/android/support/v7/mms/MmsXmlResourceParser.java rename to app/src/main/java/android/support/v7/mms/MmsXmlResourceParser.java diff --git a/src/android/support/v7/mms/PhoneNumberHelper.java b/app/src/main/java/android/support/v7/mms/PhoneNumberHelper.java similarity index 100% rename from src/android/support/v7/mms/PhoneNumberHelper.java rename to app/src/main/java/android/support/v7/mms/PhoneNumberHelper.java diff --git a/src/android/support/v7/mms/SendRequest.java b/app/src/main/java/android/support/v7/mms/SendRequest.java similarity index 100% rename from src/android/support/v7/mms/SendRequest.java rename to app/src/main/java/android/support/v7/mms/SendRequest.java diff --git a/src/android/support/v7/mms/UserAgentInfoLoader.java b/app/src/main/java/android/support/v7/mms/UserAgentInfoLoader.java similarity index 100% rename from src/android/support/v7/mms/UserAgentInfoLoader.java rename to app/src/main/java/android/support/v7/mms/UserAgentInfoLoader.java diff --git a/src/android/support/v7/mms/Utils.java b/app/src/main/java/android/support/v7/mms/Utils.java similarity index 100% rename from src/android/support/v7/mms/Utils.java rename to app/src/main/java/android/support/v7/mms/Utils.java diff --git a/src/android/support/v7/mms/pdu/AcknowledgeInd.java b/app/src/main/java/android/support/v7/mms/pdu/AcknowledgeInd.java similarity index 100% rename from src/android/support/v7/mms/pdu/AcknowledgeInd.java rename to app/src/main/java/android/support/v7/mms/pdu/AcknowledgeInd.java diff --git a/src/android/support/v7/mms/pdu/Base64.java b/app/src/main/java/android/support/v7/mms/pdu/Base64.java similarity index 100% rename from src/android/support/v7/mms/pdu/Base64.java rename to app/src/main/java/android/support/v7/mms/pdu/Base64.java diff --git a/src/android/support/v7/mms/pdu/CharacterSets.java b/app/src/main/java/android/support/v7/mms/pdu/CharacterSets.java similarity index 100% rename from src/android/support/v7/mms/pdu/CharacterSets.java rename to app/src/main/java/android/support/v7/mms/pdu/CharacterSets.java diff --git a/src/android/support/v7/mms/pdu/ContentType.java b/app/src/main/java/android/support/v7/mms/pdu/ContentType.java similarity index 100% rename from src/android/support/v7/mms/pdu/ContentType.java rename to app/src/main/java/android/support/v7/mms/pdu/ContentType.java diff --git a/src/android/support/v7/mms/pdu/DeliveryInd.java b/app/src/main/java/android/support/v7/mms/pdu/DeliveryInd.java similarity index 100% rename from src/android/support/v7/mms/pdu/DeliveryInd.java rename to app/src/main/java/android/support/v7/mms/pdu/DeliveryInd.java diff --git a/src/android/support/v7/mms/pdu/EncodedStringValue.java b/app/src/main/java/android/support/v7/mms/pdu/EncodedStringValue.java similarity index 100% rename from src/android/support/v7/mms/pdu/EncodedStringValue.java rename to app/src/main/java/android/support/v7/mms/pdu/EncodedStringValue.java diff --git a/src/android/support/v7/mms/pdu/GenericPdu.java b/app/src/main/java/android/support/v7/mms/pdu/GenericPdu.java similarity index 100% rename from src/android/support/v7/mms/pdu/GenericPdu.java rename to app/src/main/java/android/support/v7/mms/pdu/GenericPdu.java diff --git a/src/android/support/v7/mms/pdu/InvalidHeaderValueException.java b/app/src/main/java/android/support/v7/mms/pdu/InvalidHeaderValueException.java similarity index 100% rename from src/android/support/v7/mms/pdu/InvalidHeaderValueException.java rename to app/src/main/java/android/support/v7/mms/pdu/InvalidHeaderValueException.java diff --git a/src/android/support/v7/mms/pdu/MmsException.java b/app/src/main/java/android/support/v7/mms/pdu/MmsException.java similarity index 100% rename from src/android/support/v7/mms/pdu/MmsException.java rename to app/src/main/java/android/support/v7/mms/pdu/MmsException.java diff --git a/src/android/support/v7/mms/pdu/MultimediaMessagePdu.java b/app/src/main/java/android/support/v7/mms/pdu/MultimediaMessagePdu.java similarity index 100% rename from src/android/support/v7/mms/pdu/MultimediaMessagePdu.java rename to app/src/main/java/android/support/v7/mms/pdu/MultimediaMessagePdu.java diff --git a/src/android/support/v7/mms/pdu/NotificationInd.java b/app/src/main/java/android/support/v7/mms/pdu/NotificationInd.java similarity index 100% rename from src/android/support/v7/mms/pdu/NotificationInd.java rename to app/src/main/java/android/support/v7/mms/pdu/NotificationInd.java diff --git a/src/android/support/v7/mms/pdu/NotifyRespInd.java b/app/src/main/java/android/support/v7/mms/pdu/NotifyRespInd.java similarity index 100% rename from src/android/support/v7/mms/pdu/NotifyRespInd.java rename to app/src/main/java/android/support/v7/mms/pdu/NotifyRespInd.java diff --git a/src/android/support/v7/mms/pdu/PduBody.java b/app/src/main/java/android/support/v7/mms/pdu/PduBody.java similarity index 100% rename from src/android/support/v7/mms/pdu/PduBody.java rename to app/src/main/java/android/support/v7/mms/pdu/PduBody.java diff --git a/src/android/support/v7/mms/pdu/PduContentTypes.java b/app/src/main/java/android/support/v7/mms/pdu/PduContentTypes.java similarity index 100% rename from src/android/support/v7/mms/pdu/PduContentTypes.java rename to app/src/main/java/android/support/v7/mms/pdu/PduContentTypes.java diff --git a/src/android/support/v7/mms/pdu/PduHeaders.java b/app/src/main/java/android/support/v7/mms/pdu/PduHeaders.java similarity index 100% rename from src/android/support/v7/mms/pdu/PduHeaders.java rename to app/src/main/java/android/support/v7/mms/pdu/PduHeaders.java diff --git a/src/android/support/v7/mms/pdu/PduParser.java b/app/src/main/java/android/support/v7/mms/pdu/PduParser.java similarity index 100% rename from src/android/support/v7/mms/pdu/PduParser.java rename to app/src/main/java/android/support/v7/mms/pdu/PduParser.java diff --git a/src/android/support/v7/mms/pdu/PduPart.java b/app/src/main/java/android/support/v7/mms/pdu/PduPart.java similarity index 100% rename from src/android/support/v7/mms/pdu/PduPart.java rename to app/src/main/java/android/support/v7/mms/pdu/PduPart.java diff --git a/src/android/support/v7/mms/pdu/QuotedPrintable.java b/app/src/main/java/android/support/v7/mms/pdu/QuotedPrintable.java similarity index 100% rename from src/android/support/v7/mms/pdu/QuotedPrintable.java rename to app/src/main/java/android/support/v7/mms/pdu/QuotedPrintable.java diff --git a/src/android/support/v7/mms/pdu/ReadOrigInd.java b/app/src/main/java/android/support/v7/mms/pdu/ReadOrigInd.java similarity index 100% rename from src/android/support/v7/mms/pdu/ReadOrigInd.java rename to app/src/main/java/android/support/v7/mms/pdu/ReadOrigInd.java diff --git a/src/android/support/v7/mms/pdu/ReadRecInd.java b/app/src/main/java/android/support/v7/mms/pdu/ReadRecInd.java similarity index 100% rename from src/android/support/v7/mms/pdu/ReadRecInd.java rename to app/src/main/java/android/support/v7/mms/pdu/ReadRecInd.java diff --git a/src/android/support/v7/mms/pdu/RetrieveConf.java b/app/src/main/java/android/support/v7/mms/pdu/RetrieveConf.java similarity index 100% rename from src/android/support/v7/mms/pdu/RetrieveConf.java rename to app/src/main/java/android/support/v7/mms/pdu/RetrieveConf.java diff --git a/src/android/support/v7/mms/pdu/SendConf.java b/app/src/main/java/android/support/v7/mms/pdu/SendConf.java similarity index 100% rename from src/android/support/v7/mms/pdu/SendConf.java rename to app/src/main/java/android/support/v7/mms/pdu/SendConf.java diff --git a/src/android/support/v7/mms/pdu/SendReq.java b/app/src/main/java/android/support/v7/mms/pdu/SendReq.java similarity index 100% rename from src/android/support/v7/mms/pdu/SendReq.java rename to app/src/main/java/android/support/v7/mms/pdu/SendReq.java diff --git a/src/com/android/messaging/BugleApplication.java b/app/src/main/java/com/android/messaging/BugleApplication.java similarity index 100% rename from src/com/android/messaging/BugleApplication.java rename to app/src/main/java/com/android/messaging/BugleApplication.java diff --git a/src/com/android/messaging/Factory.java b/app/src/main/java/com/android/messaging/Factory.java similarity index 100% rename from src/com/android/messaging/Factory.java rename to app/src/main/java/com/android/messaging/Factory.java diff --git a/src/com/android/messaging/FactoryImpl.java b/app/src/main/java/com/android/messaging/FactoryImpl.java similarity index 100% rename from src/com/android/messaging/FactoryImpl.java rename to app/src/main/java/com/android/messaging/FactoryImpl.java diff --git a/src/com/android/messaging/datamodel/BoundCursorLoader.java b/app/src/main/java/com/android/messaging/datamodel/BoundCursorLoader.java similarity index 100% rename from src/com/android/messaging/datamodel/BoundCursorLoader.java rename to app/src/main/java/com/android/messaging/datamodel/BoundCursorLoader.java diff --git a/src/com/android/messaging/datamodel/BugleDatabaseOperations.java b/app/src/main/java/com/android/messaging/datamodel/BugleDatabaseOperations.java similarity index 100% rename from src/com/android/messaging/datamodel/BugleDatabaseOperations.java rename to app/src/main/java/com/android/messaging/datamodel/BugleDatabaseOperations.java diff --git a/src/com/android/messaging/datamodel/BugleNotifications.java b/app/src/main/java/com/android/messaging/datamodel/BugleNotifications.java similarity index 100% rename from src/com/android/messaging/datamodel/BugleNotifications.java rename to app/src/main/java/com/android/messaging/datamodel/BugleNotifications.java diff --git a/src/com/android/messaging/datamodel/BugleRecipientEntry.java b/app/src/main/java/com/android/messaging/datamodel/BugleRecipientEntry.java similarity index 100% rename from src/com/android/messaging/datamodel/BugleRecipientEntry.java rename to app/src/main/java/com/android/messaging/datamodel/BugleRecipientEntry.java diff --git a/src/com/android/messaging/datamodel/ConversationImagePartsView.java b/app/src/main/java/com/android/messaging/datamodel/ConversationImagePartsView.java similarity index 100% rename from src/com/android/messaging/datamodel/ConversationImagePartsView.java rename to app/src/main/java/com/android/messaging/datamodel/ConversationImagePartsView.java diff --git a/src/com/android/messaging/datamodel/CursorQueryData.java b/app/src/main/java/com/android/messaging/datamodel/CursorQueryData.java similarity index 100% rename from src/com/android/messaging/datamodel/CursorQueryData.java rename to app/src/main/java/com/android/messaging/datamodel/CursorQueryData.java diff --git a/src/com/android/messaging/datamodel/DataModel.java b/app/src/main/java/com/android/messaging/datamodel/DataModel.java similarity index 100% rename from src/com/android/messaging/datamodel/DataModel.java rename to app/src/main/java/com/android/messaging/datamodel/DataModel.java diff --git a/src/com/android/messaging/datamodel/DataModelImpl.java b/app/src/main/java/com/android/messaging/datamodel/DataModelImpl.java similarity index 100% rename from src/com/android/messaging/datamodel/DataModelImpl.java rename to app/src/main/java/com/android/messaging/datamodel/DataModelImpl.java diff --git a/src/com/android/messaging/datamodel/DatabaseHelper.java b/app/src/main/java/com/android/messaging/datamodel/DatabaseHelper.java similarity index 100% rename from src/com/android/messaging/datamodel/DatabaseHelper.java rename to app/src/main/java/com/android/messaging/datamodel/DatabaseHelper.java diff --git a/src/com/android/messaging/datamodel/DatabaseUpgradeHelper.java b/app/src/main/java/com/android/messaging/datamodel/DatabaseUpgradeHelper.java similarity index 100% rename from src/com/android/messaging/datamodel/DatabaseUpgradeHelper.java rename to app/src/main/java/com/android/messaging/datamodel/DatabaseUpgradeHelper.java diff --git a/src/com/android/messaging/datamodel/DatabaseWrapper.java b/app/src/main/java/com/android/messaging/datamodel/DatabaseWrapper.java similarity index 100% rename from src/com/android/messaging/datamodel/DatabaseWrapper.java rename to app/src/main/java/com/android/messaging/datamodel/DatabaseWrapper.java diff --git a/src/com/android/messaging/datamodel/FileProvider.java b/app/src/main/java/com/android/messaging/datamodel/FileProvider.java similarity index 100% rename from src/com/android/messaging/datamodel/FileProvider.java rename to app/src/main/java/com/android/messaging/datamodel/FileProvider.java diff --git a/src/com/android/messaging/datamodel/FrequentContactsCursorBuilder.java b/app/src/main/java/com/android/messaging/datamodel/FrequentContactsCursorBuilder.java similarity index 100% rename from src/com/android/messaging/datamodel/FrequentContactsCursorBuilder.java rename to app/src/main/java/com/android/messaging/datamodel/FrequentContactsCursorBuilder.java diff --git a/src/com/android/messaging/datamodel/FrequentContactsCursorQueryData.java b/app/src/main/java/com/android/messaging/datamodel/FrequentContactsCursorQueryData.java similarity index 100% rename from src/com/android/messaging/datamodel/FrequentContactsCursorQueryData.java rename to app/src/main/java/com/android/messaging/datamodel/FrequentContactsCursorQueryData.java diff --git a/src/com/android/messaging/datamodel/MediaScratchFileProvider.java b/app/src/main/java/com/android/messaging/datamodel/MediaScratchFileProvider.java similarity index 100% rename from src/com/android/messaging/datamodel/MediaScratchFileProvider.java rename to app/src/main/java/com/android/messaging/datamodel/MediaScratchFileProvider.java diff --git a/src/com/android/messaging/datamodel/MemoryCacheManager.java b/app/src/main/java/com/android/messaging/datamodel/MemoryCacheManager.java similarity index 100% rename from src/com/android/messaging/datamodel/MemoryCacheManager.java rename to app/src/main/java/com/android/messaging/datamodel/MemoryCacheManager.java diff --git a/src/com/android/messaging/datamodel/MessageNotificationState.java b/app/src/main/java/com/android/messaging/datamodel/MessageNotificationState.java similarity index 100% rename from src/com/android/messaging/datamodel/MessageNotificationState.java rename to app/src/main/java/com/android/messaging/datamodel/MessageNotificationState.java diff --git a/src/com/android/messaging/datamodel/MessageTextStats.java b/app/src/main/java/com/android/messaging/datamodel/MessageTextStats.java similarity index 100% rename from src/com/android/messaging/datamodel/MessageTextStats.java rename to app/src/main/java/com/android/messaging/datamodel/MessageTextStats.java diff --git a/src/com/android/messaging/datamodel/MessagingContentProvider.java b/app/src/main/java/com/android/messaging/datamodel/MessagingContentProvider.java similarity index 100% rename from src/com/android/messaging/datamodel/MessagingContentProvider.java rename to app/src/main/java/com/android/messaging/datamodel/MessagingContentProvider.java diff --git a/src/com/android/messaging/datamodel/MmsFileProvider.java b/app/src/main/java/com/android/messaging/datamodel/MmsFileProvider.java similarity index 100% rename from src/com/android/messaging/datamodel/MmsFileProvider.java rename to app/src/main/java/com/android/messaging/datamodel/MmsFileProvider.java diff --git a/src/com/android/messaging/datamodel/NoConfirmationSmsSendService.java b/app/src/main/java/com/android/messaging/datamodel/NoConfirmationSmsSendService.java similarity index 100% rename from src/com/android/messaging/datamodel/NoConfirmationSmsSendService.java rename to app/src/main/java/com/android/messaging/datamodel/NoConfirmationSmsSendService.java diff --git a/src/com/android/messaging/datamodel/NotificationState.java b/app/src/main/java/com/android/messaging/datamodel/NotificationState.java similarity index 100% rename from src/com/android/messaging/datamodel/NotificationState.java rename to app/src/main/java/com/android/messaging/datamodel/NotificationState.java diff --git a/src/com/android/messaging/datamodel/ParticipantRefresh.java b/app/src/main/java/com/android/messaging/datamodel/ParticipantRefresh.java similarity index 100% rename from src/com/android/messaging/datamodel/ParticipantRefresh.java rename to app/src/main/java/com/android/messaging/datamodel/ParticipantRefresh.java diff --git a/src/com/android/messaging/datamodel/SyncManager.java b/app/src/main/java/com/android/messaging/datamodel/SyncManager.java similarity index 100% rename from src/com/android/messaging/datamodel/SyncManager.java rename to app/src/main/java/com/android/messaging/datamodel/SyncManager.java diff --git a/src/com/android/messaging/datamodel/action/Action.java b/app/src/main/java/com/android/messaging/datamodel/action/Action.java similarity index 100% rename from src/com/android/messaging/datamodel/action/Action.java rename to app/src/main/java/com/android/messaging/datamodel/action/Action.java diff --git a/src/com/android/messaging/datamodel/action/ActionMonitor.java b/app/src/main/java/com/android/messaging/datamodel/action/ActionMonitor.java similarity index 100% rename from src/com/android/messaging/datamodel/action/ActionMonitor.java rename to app/src/main/java/com/android/messaging/datamodel/action/ActionMonitor.java diff --git a/src/com/android/messaging/datamodel/action/ActionService.java b/app/src/main/java/com/android/messaging/datamodel/action/ActionService.java similarity index 100% rename from src/com/android/messaging/datamodel/action/ActionService.java rename to app/src/main/java/com/android/messaging/datamodel/action/ActionService.java diff --git a/src/com/android/messaging/datamodel/action/ActionServiceImpl.java b/app/src/main/java/com/android/messaging/datamodel/action/ActionServiceImpl.java similarity index 100% rename from src/com/android/messaging/datamodel/action/ActionServiceImpl.java rename to app/src/main/java/com/android/messaging/datamodel/action/ActionServiceImpl.java diff --git a/src/com/android/messaging/datamodel/action/BackgroundWorker.java b/app/src/main/java/com/android/messaging/datamodel/action/BackgroundWorker.java similarity index 100% rename from src/com/android/messaging/datamodel/action/BackgroundWorker.java rename to app/src/main/java/com/android/messaging/datamodel/action/BackgroundWorker.java diff --git a/src/com/android/messaging/datamodel/action/BackgroundWorkerService.java b/app/src/main/java/com/android/messaging/datamodel/action/BackgroundWorkerService.java similarity index 100% rename from src/com/android/messaging/datamodel/action/BackgroundWorkerService.java rename to app/src/main/java/com/android/messaging/datamodel/action/BackgroundWorkerService.java diff --git a/src/com/android/messaging/datamodel/action/BugleActionToasts.java b/app/src/main/java/com/android/messaging/datamodel/action/BugleActionToasts.java similarity index 100% rename from src/com/android/messaging/datamodel/action/BugleActionToasts.java rename to app/src/main/java/com/android/messaging/datamodel/action/BugleActionToasts.java diff --git a/src/com/android/messaging/datamodel/action/DeleteConversationAction.java b/app/src/main/java/com/android/messaging/datamodel/action/DeleteConversationAction.java similarity index 100% rename from src/com/android/messaging/datamodel/action/DeleteConversationAction.java rename to app/src/main/java/com/android/messaging/datamodel/action/DeleteConversationAction.java diff --git a/src/com/android/messaging/datamodel/action/DeleteMessageAction.java b/app/src/main/java/com/android/messaging/datamodel/action/DeleteMessageAction.java similarity index 100% rename from src/com/android/messaging/datamodel/action/DeleteMessageAction.java rename to app/src/main/java/com/android/messaging/datamodel/action/DeleteMessageAction.java diff --git a/src/com/android/messaging/datamodel/action/DownloadMmsAction.java b/app/src/main/java/com/android/messaging/datamodel/action/DownloadMmsAction.java similarity index 100% rename from src/com/android/messaging/datamodel/action/DownloadMmsAction.java rename to app/src/main/java/com/android/messaging/datamodel/action/DownloadMmsAction.java diff --git a/src/com/android/messaging/datamodel/action/FixupMessageStatusOnStartupAction.java b/app/src/main/java/com/android/messaging/datamodel/action/FixupMessageStatusOnStartupAction.java similarity index 100% rename from src/com/android/messaging/datamodel/action/FixupMessageStatusOnStartupAction.java rename to app/src/main/java/com/android/messaging/datamodel/action/FixupMessageStatusOnStartupAction.java diff --git a/src/com/android/messaging/datamodel/action/GetOrCreateConversationAction.java b/app/src/main/java/com/android/messaging/datamodel/action/GetOrCreateConversationAction.java similarity index 100% rename from src/com/android/messaging/datamodel/action/GetOrCreateConversationAction.java rename to app/src/main/java/com/android/messaging/datamodel/action/GetOrCreateConversationAction.java diff --git a/src/com/android/messaging/datamodel/action/InsertNewMessageAction.java b/app/src/main/java/com/android/messaging/datamodel/action/InsertNewMessageAction.java similarity index 100% rename from src/com/android/messaging/datamodel/action/InsertNewMessageAction.java rename to app/src/main/java/com/android/messaging/datamodel/action/InsertNewMessageAction.java diff --git a/src/com/android/messaging/datamodel/action/MarkAsReadAction.java b/app/src/main/java/com/android/messaging/datamodel/action/MarkAsReadAction.java similarity index 100% rename from src/com/android/messaging/datamodel/action/MarkAsReadAction.java rename to app/src/main/java/com/android/messaging/datamodel/action/MarkAsReadAction.java diff --git a/src/com/android/messaging/datamodel/action/MarkAsSeenAction.java b/app/src/main/java/com/android/messaging/datamodel/action/MarkAsSeenAction.java similarity index 100% rename from src/com/android/messaging/datamodel/action/MarkAsSeenAction.java rename to app/src/main/java/com/android/messaging/datamodel/action/MarkAsSeenAction.java diff --git a/src/com/android/messaging/datamodel/action/ProcessDeliveryReportAction.java b/app/src/main/java/com/android/messaging/datamodel/action/ProcessDeliveryReportAction.java similarity index 100% rename from src/com/android/messaging/datamodel/action/ProcessDeliveryReportAction.java rename to app/src/main/java/com/android/messaging/datamodel/action/ProcessDeliveryReportAction.java diff --git a/src/com/android/messaging/datamodel/action/ProcessDownloadedMmsAction.java b/app/src/main/java/com/android/messaging/datamodel/action/ProcessDownloadedMmsAction.java similarity index 100% rename from src/com/android/messaging/datamodel/action/ProcessDownloadedMmsAction.java rename to app/src/main/java/com/android/messaging/datamodel/action/ProcessDownloadedMmsAction.java diff --git a/src/com/android/messaging/datamodel/action/ProcessPendingMessagesAction.java b/app/src/main/java/com/android/messaging/datamodel/action/ProcessPendingMessagesAction.java similarity index 100% rename from src/com/android/messaging/datamodel/action/ProcessPendingMessagesAction.java rename to app/src/main/java/com/android/messaging/datamodel/action/ProcessPendingMessagesAction.java diff --git a/src/com/android/messaging/datamodel/action/ProcessSentMessageAction.java b/app/src/main/java/com/android/messaging/datamodel/action/ProcessSentMessageAction.java similarity index 100% rename from src/com/android/messaging/datamodel/action/ProcessSentMessageAction.java rename to app/src/main/java/com/android/messaging/datamodel/action/ProcessSentMessageAction.java diff --git a/src/com/android/messaging/datamodel/action/ReadDraftDataAction.java b/app/src/main/java/com/android/messaging/datamodel/action/ReadDraftDataAction.java similarity index 100% rename from src/com/android/messaging/datamodel/action/ReadDraftDataAction.java rename to app/src/main/java/com/android/messaging/datamodel/action/ReadDraftDataAction.java diff --git a/src/com/android/messaging/datamodel/action/ReceiveMmsMessageAction.java b/app/src/main/java/com/android/messaging/datamodel/action/ReceiveMmsMessageAction.java similarity index 100% rename from src/com/android/messaging/datamodel/action/ReceiveMmsMessageAction.java rename to app/src/main/java/com/android/messaging/datamodel/action/ReceiveMmsMessageAction.java diff --git a/src/com/android/messaging/datamodel/action/ReceiveSmsMessageAction.java b/app/src/main/java/com/android/messaging/datamodel/action/ReceiveSmsMessageAction.java similarity index 100% rename from src/com/android/messaging/datamodel/action/ReceiveSmsMessageAction.java rename to app/src/main/java/com/android/messaging/datamodel/action/ReceiveSmsMessageAction.java diff --git a/src/com/android/messaging/datamodel/action/RedownloadMmsAction.java b/app/src/main/java/com/android/messaging/datamodel/action/RedownloadMmsAction.java similarity index 100% rename from src/com/android/messaging/datamodel/action/RedownloadMmsAction.java rename to app/src/main/java/com/android/messaging/datamodel/action/RedownloadMmsAction.java diff --git a/src/com/android/messaging/datamodel/action/ResendMessageAction.java b/app/src/main/java/com/android/messaging/datamodel/action/ResendMessageAction.java similarity index 100% rename from src/com/android/messaging/datamodel/action/ResendMessageAction.java rename to app/src/main/java/com/android/messaging/datamodel/action/ResendMessageAction.java diff --git a/src/com/android/messaging/datamodel/action/SendMessageAction.java b/app/src/main/java/com/android/messaging/datamodel/action/SendMessageAction.java similarity index 100% rename from src/com/android/messaging/datamodel/action/SendMessageAction.java rename to app/src/main/java/com/android/messaging/datamodel/action/SendMessageAction.java diff --git a/src/com/android/messaging/datamodel/action/SyncCursorPair.java b/app/src/main/java/com/android/messaging/datamodel/action/SyncCursorPair.java similarity index 100% rename from src/com/android/messaging/datamodel/action/SyncCursorPair.java rename to app/src/main/java/com/android/messaging/datamodel/action/SyncCursorPair.java diff --git a/src/com/android/messaging/datamodel/action/SyncMessageBatch.java b/app/src/main/java/com/android/messaging/datamodel/action/SyncMessageBatch.java similarity index 100% rename from src/com/android/messaging/datamodel/action/SyncMessageBatch.java rename to app/src/main/java/com/android/messaging/datamodel/action/SyncMessageBatch.java diff --git a/src/com/android/messaging/datamodel/action/SyncMessagesAction.java b/app/src/main/java/com/android/messaging/datamodel/action/SyncMessagesAction.java similarity index 100% rename from src/com/android/messaging/datamodel/action/SyncMessagesAction.java rename to app/src/main/java/com/android/messaging/datamodel/action/SyncMessagesAction.java diff --git a/src/com/android/messaging/datamodel/action/UpdateConversationArchiveStatusAction.java b/app/src/main/java/com/android/messaging/datamodel/action/UpdateConversationArchiveStatusAction.java similarity index 100% rename from src/com/android/messaging/datamodel/action/UpdateConversationArchiveStatusAction.java rename to app/src/main/java/com/android/messaging/datamodel/action/UpdateConversationArchiveStatusAction.java diff --git a/src/com/android/messaging/datamodel/action/UpdateDestinationBlockedAction.java b/app/src/main/java/com/android/messaging/datamodel/action/UpdateDestinationBlockedAction.java similarity index 100% rename from src/com/android/messaging/datamodel/action/UpdateDestinationBlockedAction.java rename to app/src/main/java/com/android/messaging/datamodel/action/UpdateDestinationBlockedAction.java diff --git a/src/com/android/messaging/datamodel/action/UpdateMessageNotificationAction.java b/app/src/main/java/com/android/messaging/datamodel/action/UpdateMessageNotificationAction.java similarity index 100% rename from src/com/android/messaging/datamodel/action/UpdateMessageNotificationAction.java rename to app/src/main/java/com/android/messaging/datamodel/action/UpdateMessageNotificationAction.java diff --git a/src/com/android/messaging/datamodel/action/UpdateMessagePartSizeAction.java b/app/src/main/java/com/android/messaging/datamodel/action/UpdateMessagePartSizeAction.java similarity index 100% rename from src/com/android/messaging/datamodel/action/UpdateMessagePartSizeAction.java rename to app/src/main/java/com/android/messaging/datamodel/action/UpdateMessagePartSizeAction.java diff --git a/src/com/android/messaging/datamodel/action/WriteDraftMessageAction.java b/app/src/main/java/com/android/messaging/datamodel/action/WriteDraftMessageAction.java similarity index 100% rename from src/com/android/messaging/datamodel/action/WriteDraftMessageAction.java rename to app/src/main/java/com/android/messaging/datamodel/action/WriteDraftMessageAction.java diff --git a/src/com/android/messaging/datamodel/binding/BindableData.java b/app/src/main/java/com/android/messaging/datamodel/binding/BindableData.java similarity index 100% rename from src/com/android/messaging/datamodel/binding/BindableData.java rename to app/src/main/java/com/android/messaging/datamodel/binding/BindableData.java diff --git a/src/com/android/messaging/datamodel/binding/BindableOnceData.java b/app/src/main/java/com/android/messaging/datamodel/binding/BindableOnceData.java similarity index 100% rename from src/com/android/messaging/datamodel/binding/BindableOnceData.java rename to app/src/main/java/com/android/messaging/datamodel/binding/BindableOnceData.java diff --git a/src/com/android/messaging/datamodel/binding/Binding.java b/app/src/main/java/com/android/messaging/datamodel/binding/Binding.java similarity index 100% rename from src/com/android/messaging/datamodel/binding/Binding.java rename to app/src/main/java/com/android/messaging/datamodel/binding/Binding.java diff --git a/src/com/android/messaging/datamodel/binding/BindingBase.java b/app/src/main/java/com/android/messaging/datamodel/binding/BindingBase.java similarity index 100% rename from src/com/android/messaging/datamodel/binding/BindingBase.java rename to app/src/main/java/com/android/messaging/datamodel/binding/BindingBase.java diff --git a/src/com/android/messaging/datamodel/binding/DetachableBinding.java b/app/src/main/java/com/android/messaging/datamodel/binding/DetachableBinding.java similarity index 100% rename from src/com/android/messaging/datamodel/binding/DetachableBinding.java rename to app/src/main/java/com/android/messaging/datamodel/binding/DetachableBinding.java diff --git a/src/com/android/messaging/datamodel/binding/ImmutableBindingRef.java b/app/src/main/java/com/android/messaging/datamodel/binding/ImmutableBindingRef.java similarity index 100% rename from src/com/android/messaging/datamodel/binding/ImmutableBindingRef.java rename to app/src/main/java/com/android/messaging/datamodel/binding/ImmutableBindingRef.java diff --git a/src/com/android/messaging/datamodel/data/BlockedParticipantsData.java b/app/src/main/java/com/android/messaging/datamodel/data/BlockedParticipantsData.java similarity index 100% rename from src/com/android/messaging/datamodel/data/BlockedParticipantsData.java rename to app/src/main/java/com/android/messaging/datamodel/data/BlockedParticipantsData.java diff --git a/src/com/android/messaging/datamodel/data/ContactListItemData.java b/app/src/main/java/com/android/messaging/datamodel/data/ContactListItemData.java similarity index 100% rename from src/com/android/messaging/datamodel/data/ContactListItemData.java rename to app/src/main/java/com/android/messaging/datamodel/data/ContactListItemData.java diff --git a/src/com/android/messaging/datamodel/data/ContactPickerData.java b/app/src/main/java/com/android/messaging/datamodel/data/ContactPickerData.java similarity index 100% rename from src/com/android/messaging/datamodel/data/ContactPickerData.java rename to app/src/main/java/com/android/messaging/datamodel/data/ContactPickerData.java diff --git a/src/com/android/messaging/datamodel/data/ConversationData.java b/app/src/main/java/com/android/messaging/datamodel/data/ConversationData.java similarity index 100% rename from src/com/android/messaging/datamodel/data/ConversationData.java rename to app/src/main/java/com/android/messaging/datamodel/data/ConversationData.java diff --git a/src/com/android/messaging/datamodel/data/ConversationListData.java b/app/src/main/java/com/android/messaging/datamodel/data/ConversationListData.java similarity index 100% rename from src/com/android/messaging/datamodel/data/ConversationListData.java rename to app/src/main/java/com/android/messaging/datamodel/data/ConversationListData.java diff --git a/src/com/android/messaging/datamodel/data/ConversationListItemData.java b/app/src/main/java/com/android/messaging/datamodel/data/ConversationListItemData.java similarity index 100% rename from src/com/android/messaging/datamodel/data/ConversationListItemData.java rename to app/src/main/java/com/android/messaging/datamodel/data/ConversationListItemData.java diff --git a/src/com/android/messaging/datamodel/data/ConversationMessageBubbleData.java b/app/src/main/java/com/android/messaging/datamodel/data/ConversationMessageBubbleData.java similarity index 100% rename from src/com/android/messaging/datamodel/data/ConversationMessageBubbleData.java rename to app/src/main/java/com/android/messaging/datamodel/data/ConversationMessageBubbleData.java diff --git a/src/com/android/messaging/datamodel/data/ConversationMessageData.java b/app/src/main/java/com/android/messaging/datamodel/data/ConversationMessageData.java similarity index 100% rename from src/com/android/messaging/datamodel/data/ConversationMessageData.java rename to app/src/main/java/com/android/messaging/datamodel/data/ConversationMessageData.java diff --git a/src/com/android/messaging/datamodel/data/ConversationParticipantsData.java b/app/src/main/java/com/android/messaging/datamodel/data/ConversationParticipantsData.java similarity index 100% rename from src/com/android/messaging/datamodel/data/ConversationParticipantsData.java rename to app/src/main/java/com/android/messaging/datamodel/data/ConversationParticipantsData.java diff --git a/src/com/android/messaging/datamodel/data/DraftMessageData.java b/app/src/main/java/com/android/messaging/datamodel/data/DraftMessageData.java similarity index 100% rename from src/com/android/messaging/datamodel/data/DraftMessageData.java rename to app/src/main/java/com/android/messaging/datamodel/data/DraftMessageData.java diff --git a/src/com/android/messaging/datamodel/data/LaunchConversationData.java b/app/src/main/java/com/android/messaging/datamodel/data/LaunchConversationData.java similarity index 100% rename from src/com/android/messaging/datamodel/data/LaunchConversationData.java rename to app/src/main/java/com/android/messaging/datamodel/data/LaunchConversationData.java diff --git a/src/com/android/messaging/datamodel/data/MediaPickerData.java b/app/src/main/java/com/android/messaging/datamodel/data/MediaPickerData.java similarity index 100% rename from src/com/android/messaging/datamodel/data/MediaPickerData.java rename to app/src/main/java/com/android/messaging/datamodel/data/MediaPickerData.java diff --git a/src/com/android/messaging/datamodel/data/MediaPickerMessagePartData.java b/app/src/main/java/com/android/messaging/datamodel/data/MediaPickerMessagePartData.java similarity index 100% rename from src/com/android/messaging/datamodel/data/MediaPickerMessagePartData.java rename to app/src/main/java/com/android/messaging/datamodel/data/MediaPickerMessagePartData.java diff --git a/src/com/android/messaging/datamodel/data/MessageData.java b/app/src/main/java/com/android/messaging/datamodel/data/MessageData.java similarity index 100% rename from src/com/android/messaging/datamodel/data/MessageData.java rename to app/src/main/java/com/android/messaging/datamodel/data/MessageData.java diff --git a/src/com/android/messaging/datamodel/data/MessagePartData.java b/app/src/main/java/com/android/messaging/datamodel/data/MessagePartData.java similarity index 100% rename from src/com/android/messaging/datamodel/data/MessagePartData.java rename to app/src/main/java/com/android/messaging/datamodel/data/MessagePartData.java diff --git a/src/com/android/messaging/datamodel/data/ParticipantData.java b/app/src/main/java/com/android/messaging/datamodel/data/ParticipantData.java similarity index 100% rename from src/com/android/messaging/datamodel/data/ParticipantData.java rename to app/src/main/java/com/android/messaging/datamodel/data/ParticipantData.java diff --git a/src/com/android/messaging/datamodel/data/ParticipantListItemData.java b/app/src/main/java/com/android/messaging/datamodel/data/ParticipantListItemData.java similarity index 100% rename from src/com/android/messaging/datamodel/data/ParticipantListItemData.java rename to app/src/main/java/com/android/messaging/datamodel/data/ParticipantListItemData.java diff --git a/src/com/android/messaging/datamodel/data/PendingAttachmentData.java b/app/src/main/java/com/android/messaging/datamodel/data/PendingAttachmentData.java similarity index 100% rename from src/com/android/messaging/datamodel/data/PendingAttachmentData.java rename to app/src/main/java/com/android/messaging/datamodel/data/PendingAttachmentData.java diff --git a/src/com/android/messaging/datamodel/data/PeopleAndOptionsData.java b/app/src/main/java/com/android/messaging/datamodel/data/PeopleAndOptionsData.java similarity index 100% rename from src/com/android/messaging/datamodel/data/PeopleAndOptionsData.java rename to app/src/main/java/com/android/messaging/datamodel/data/PeopleAndOptionsData.java diff --git a/src/com/android/messaging/datamodel/data/PeopleOptionsItemData.java b/app/src/main/java/com/android/messaging/datamodel/data/PeopleOptionsItemData.java similarity index 100% rename from src/com/android/messaging/datamodel/data/PeopleOptionsItemData.java rename to app/src/main/java/com/android/messaging/datamodel/data/PeopleOptionsItemData.java diff --git a/src/com/android/messaging/datamodel/data/PersonItemData.java b/app/src/main/java/com/android/messaging/datamodel/data/PersonItemData.java similarity index 100% rename from src/com/android/messaging/datamodel/data/PersonItemData.java rename to app/src/main/java/com/android/messaging/datamodel/data/PersonItemData.java diff --git a/src/com/android/messaging/datamodel/data/SelfParticipantsData.java b/app/src/main/java/com/android/messaging/datamodel/data/SelfParticipantsData.java similarity index 100% rename from src/com/android/messaging/datamodel/data/SelfParticipantsData.java rename to app/src/main/java/com/android/messaging/datamodel/data/SelfParticipantsData.java diff --git a/src/com/android/messaging/datamodel/data/SettingsData.java b/app/src/main/java/com/android/messaging/datamodel/data/SettingsData.java similarity index 100% rename from src/com/android/messaging/datamodel/data/SettingsData.java rename to app/src/main/java/com/android/messaging/datamodel/data/SettingsData.java diff --git a/src/com/android/messaging/datamodel/data/SubscriptionListData.java b/app/src/main/java/com/android/messaging/datamodel/data/SubscriptionListData.java similarity index 100% rename from src/com/android/messaging/datamodel/data/SubscriptionListData.java rename to app/src/main/java/com/android/messaging/datamodel/data/SubscriptionListData.java diff --git a/src/com/android/messaging/datamodel/data/VCardContactItemData.java b/app/src/main/java/com/android/messaging/datamodel/data/VCardContactItemData.java similarity index 100% rename from src/com/android/messaging/datamodel/data/VCardContactItemData.java rename to app/src/main/java/com/android/messaging/datamodel/data/VCardContactItemData.java diff --git a/src/com/android/messaging/datamodel/media/AsyncMediaRequestWrapper.java b/app/src/main/java/com/android/messaging/datamodel/media/AsyncMediaRequestWrapper.java similarity index 100% rename from src/com/android/messaging/datamodel/media/AsyncMediaRequestWrapper.java rename to app/src/main/java/com/android/messaging/datamodel/media/AsyncMediaRequestWrapper.java diff --git a/src/com/android/messaging/datamodel/media/AvatarGroupRequestDescriptor.java b/app/src/main/java/com/android/messaging/datamodel/media/AvatarGroupRequestDescriptor.java similarity index 100% rename from src/com/android/messaging/datamodel/media/AvatarGroupRequestDescriptor.java rename to app/src/main/java/com/android/messaging/datamodel/media/AvatarGroupRequestDescriptor.java diff --git a/src/com/android/messaging/datamodel/media/AvatarRequest.java b/app/src/main/java/com/android/messaging/datamodel/media/AvatarRequest.java similarity index 100% rename from src/com/android/messaging/datamodel/media/AvatarRequest.java rename to app/src/main/java/com/android/messaging/datamodel/media/AvatarRequest.java diff --git a/src/com/android/messaging/datamodel/media/AvatarRequestDescriptor.java b/app/src/main/java/com/android/messaging/datamodel/media/AvatarRequestDescriptor.java similarity index 100% rename from src/com/android/messaging/datamodel/media/AvatarRequestDescriptor.java rename to app/src/main/java/com/android/messaging/datamodel/media/AvatarRequestDescriptor.java diff --git a/src/com/android/messaging/datamodel/media/BindableMediaRequest.java b/app/src/main/java/com/android/messaging/datamodel/media/BindableMediaRequest.java similarity index 100% rename from src/com/android/messaging/datamodel/media/BindableMediaRequest.java rename to app/src/main/java/com/android/messaging/datamodel/media/BindableMediaRequest.java diff --git a/src/com/android/messaging/datamodel/media/BugleMediaCacheManager.java b/app/src/main/java/com/android/messaging/datamodel/media/BugleMediaCacheManager.java similarity index 100% rename from src/com/android/messaging/datamodel/media/BugleMediaCacheManager.java rename to app/src/main/java/com/android/messaging/datamodel/media/BugleMediaCacheManager.java diff --git a/src/com/android/messaging/datamodel/media/CompositeImageRequest.java b/app/src/main/java/com/android/messaging/datamodel/media/CompositeImageRequest.java similarity index 100% rename from src/com/android/messaging/datamodel/media/CompositeImageRequest.java rename to app/src/main/java/com/android/messaging/datamodel/media/CompositeImageRequest.java diff --git a/src/com/android/messaging/datamodel/media/CompositeImageRequestDescriptor.java b/app/src/main/java/com/android/messaging/datamodel/media/CompositeImageRequestDescriptor.java similarity index 100% rename from src/com/android/messaging/datamodel/media/CompositeImageRequestDescriptor.java rename to app/src/main/java/com/android/messaging/datamodel/media/CompositeImageRequestDescriptor.java diff --git a/src/com/android/messaging/datamodel/media/CustomVCardEntry.java b/app/src/main/java/com/android/messaging/datamodel/media/CustomVCardEntry.java similarity index 100% rename from src/com/android/messaging/datamodel/media/CustomVCardEntry.java rename to app/src/main/java/com/android/messaging/datamodel/media/CustomVCardEntry.java diff --git a/src/com/android/messaging/datamodel/media/CustomVCardEntryConstructor.java b/app/src/main/java/com/android/messaging/datamodel/media/CustomVCardEntryConstructor.java similarity index 100% rename from src/com/android/messaging/datamodel/media/CustomVCardEntryConstructor.java rename to app/src/main/java/com/android/messaging/datamodel/media/CustomVCardEntryConstructor.java diff --git a/src/com/android/messaging/datamodel/media/DecodedImageResource.java b/app/src/main/java/com/android/messaging/datamodel/media/DecodedImageResource.java similarity index 100% rename from src/com/android/messaging/datamodel/media/DecodedImageResource.java rename to app/src/main/java/com/android/messaging/datamodel/media/DecodedImageResource.java diff --git a/src/com/android/messaging/datamodel/media/EncodedImageResource.java b/app/src/main/java/com/android/messaging/datamodel/media/EncodedImageResource.java similarity index 100% rename from src/com/android/messaging/datamodel/media/EncodedImageResource.java rename to app/src/main/java/com/android/messaging/datamodel/media/EncodedImageResource.java diff --git a/src/com/android/messaging/datamodel/media/FileImageRequest.java b/app/src/main/java/com/android/messaging/datamodel/media/FileImageRequest.java similarity index 100% rename from src/com/android/messaging/datamodel/media/FileImageRequest.java rename to app/src/main/java/com/android/messaging/datamodel/media/FileImageRequest.java diff --git a/src/com/android/messaging/datamodel/media/FileImageRequestDescriptor.java b/app/src/main/java/com/android/messaging/datamodel/media/FileImageRequestDescriptor.java similarity index 100% rename from src/com/android/messaging/datamodel/media/FileImageRequestDescriptor.java rename to app/src/main/java/com/android/messaging/datamodel/media/FileImageRequestDescriptor.java diff --git a/src/com/android/messaging/datamodel/media/GifImageResource.java b/app/src/main/java/com/android/messaging/datamodel/media/GifImageResource.java similarity index 100% rename from src/com/android/messaging/datamodel/media/GifImageResource.java rename to app/src/main/java/com/android/messaging/datamodel/media/GifImageResource.java diff --git a/src/com/android/messaging/datamodel/media/ImageRequest.java b/app/src/main/java/com/android/messaging/datamodel/media/ImageRequest.java similarity index 100% rename from src/com/android/messaging/datamodel/media/ImageRequest.java rename to app/src/main/java/com/android/messaging/datamodel/media/ImageRequest.java diff --git a/src/com/android/messaging/datamodel/media/ImageRequestDescriptor.java b/app/src/main/java/com/android/messaging/datamodel/media/ImageRequestDescriptor.java similarity index 100% rename from src/com/android/messaging/datamodel/media/ImageRequestDescriptor.java rename to app/src/main/java/com/android/messaging/datamodel/media/ImageRequestDescriptor.java diff --git a/src/com/android/messaging/datamodel/media/ImageResource.java b/app/src/main/java/com/android/messaging/datamodel/media/ImageResource.java similarity index 100% rename from src/com/android/messaging/datamodel/media/ImageResource.java rename to app/src/main/java/com/android/messaging/datamodel/media/ImageResource.java diff --git a/src/com/android/messaging/datamodel/media/MediaBytes.java b/app/src/main/java/com/android/messaging/datamodel/media/MediaBytes.java similarity index 100% rename from src/com/android/messaging/datamodel/media/MediaBytes.java rename to app/src/main/java/com/android/messaging/datamodel/media/MediaBytes.java diff --git a/src/com/android/messaging/datamodel/media/MediaCache.java b/app/src/main/java/com/android/messaging/datamodel/media/MediaCache.java similarity index 100% rename from src/com/android/messaging/datamodel/media/MediaCache.java rename to app/src/main/java/com/android/messaging/datamodel/media/MediaCache.java diff --git a/src/com/android/messaging/datamodel/media/MediaCacheManager.java b/app/src/main/java/com/android/messaging/datamodel/media/MediaCacheManager.java similarity index 100% rename from src/com/android/messaging/datamodel/media/MediaCacheManager.java rename to app/src/main/java/com/android/messaging/datamodel/media/MediaCacheManager.java diff --git a/src/com/android/messaging/datamodel/media/MediaRequest.java b/app/src/main/java/com/android/messaging/datamodel/media/MediaRequest.java similarity index 100% rename from src/com/android/messaging/datamodel/media/MediaRequest.java rename to app/src/main/java/com/android/messaging/datamodel/media/MediaRequest.java diff --git a/src/com/android/messaging/datamodel/media/MediaRequestDescriptor.java b/app/src/main/java/com/android/messaging/datamodel/media/MediaRequestDescriptor.java similarity index 100% rename from src/com/android/messaging/datamodel/media/MediaRequestDescriptor.java rename to app/src/main/java/com/android/messaging/datamodel/media/MediaRequestDescriptor.java diff --git a/src/com/android/messaging/datamodel/media/MediaResourceManager.java b/app/src/main/java/com/android/messaging/datamodel/media/MediaResourceManager.java similarity index 100% rename from src/com/android/messaging/datamodel/media/MediaResourceManager.java rename to app/src/main/java/com/android/messaging/datamodel/media/MediaResourceManager.java diff --git a/src/com/android/messaging/datamodel/media/MessagePartImageRequestDescriptor.java b/app/src/main/java/com/android/messaging/datamodel/media/MessagePartImageRequestDescriptor.java similarity index 100% rename from src/com/android/messaging/datamodel/media/MessagePartImageRequestDescriptor.java rename to app/src/main/java/com/android/messaging/datamodel/media/MessagePartImageRequestDescriptor.java diff --git a/src/com/android/messaging/datamodel/media/MessagePartVideoThumbnailRequestDescriptor.java b/app/src/main/java/com/android/messaging/datamodel/media/MessagePartVideoThumbnailRequestDescriptor.java similarity index 100% rename from src/com/android/messaging/datamodel/media/MessagePartVideoThumbnailRequestDescriptor.java rename to app/src/main/java/com/android/messaging/datamodel/media/MessagePartVideoThumbnailRequestDescriptor.java diff --git a/src/com/android/messaging/datamodel/media/NetworkUriImageRequest.java b/app/src/main/java/com/android/messaging/datamodel/media/NetworkUriImageRequest.java similarity index 100% rename from src/com/android/messaging/datamodel/media/NetworkUriImageRequest.java rename to app/src/main/java/com/android/messaging/datamodel/media/NetworkUriImageRequest.java diff --git a/src/com/android/messaging/datamodel/media/PoolableImageCache.java b/app/src/main/java/com/android/messaging/datamodel/media/PoolableImageCache.java similarity index 100% rename from src/com/android/messaging/datamodel/media/PoolableImageCache.java rename to app/src/main/java/com/android/messaging/datamodel/media/PoolableImageCache.java diff --git a/src/com/android/messaging/datamodel/media/RefCountedMediaResource.java b/app/src/main/java/com/android/messaging/datamodel/media/RefCountedMediaResource.java similarity index 100% rename from src/com/android/messaging/datamodel/media/RefCountedMediaResource.java rename to app/src/main/java/com/android/messaging/datamodel/media/RefCountedMediaResource.java diff --git a/src/com/android/messaging/datamodel/media/SimSelectorAvatarRequest.java b/app/src/main/java/com/android/messaging/datamodel/media/SimSelectorAvatarRequest.java similarity index 100% rename from src/com/android/messaging/datamodel/media/SimSelectorAvatarRequest.java rename to app/src/main/java/com/android/messaging/datamodel/media/SimSelectorAvatarRequest.java diff --git a/src/com/android/messaging/datamodel/media/UriImageRequest.java b/app/src/main/java/com/android/messaging/datamodel/media/UriImageRequest.java similarity index 100% rename from src/com/android/messaging/datamodel/media/UriImageRequest.java rename to app/src/main/java/com/android/messaging/datamodel/media/UriImageRequest.java diff --git a/src/com/android/messaging/datamodel/media/UriImageRequestDescriptor.java b/app/src/main/java/com/android/messaging/datamodel/media/UriImageRequestDescriptor.java similarity index 100% rename from src/com/android/messaging/datamodel/media/UriImageRequestDescriptor.java rename to app/src/main/java/com/android/messaging/datamodel/media/UriImageRequestDescriptor.java diff --git a/src/com/android/messaging/datamodel/media/VCardRequest.java b/app/src/main/java/com/android/messaging/datamodel/media/VCardRequest.java similarity index 100% rename from src/com/android/messaging/datamodel/media/VCardRequest.java rename to app/src/main/java/com/android/messaging/datamodel/media/VCardRequest.java diff --git a/src/com/android/messaging/datamodel/media/VCardRequestDescriptor.java b/app/src/main/java/com/android/messaging/datamodel/media/VCardRequestDescriptor.java similarity index 100% rename from src/com/android/messaging/datamodel/media/VCardRequestDescriptor.java rename to app/src/main/java/com/android/messaging/datamodel/media/VCardRequestDescriptor.java diff --git a/src/com/android/messaging/datamodel/media/VCardResource.java b/app/src/main/java/com/android/messaging/datamodel/media/VCardResource.java similarity index 100% rename from src/com/android/messaging/datamodel/media/VCardResource.java rename to app/src/main/java/com/android/messaging/datamodel/media/VCardResource.java diff --git a/src/com/android/messaging/datamodel/media/VCardResourceEntry.java b/app/src/main/java/com/android/messaging/datamodel/media/VCardResourceEntry.java similarity index 100% rename from src/com/android/messaging/datamodel/media/VCardResourceEntry.java rename to app/src/main/java/com/android/messaging/datamodel/media/VCardResourceEntry.java diff --git a/src/com/android/messaging/datamodel/media/VideoThumbnailRequest.java b/app/src/main/java/com/android/messaging/datamodel/media/VideoThumbnailRequest.java similarity index 100% rename from src/com/android/messaging/datamodel/media/VideoThumbnailRequest.java rename to app/src/main/java/com/android/messaging/datamodel/media/VideoThumbnailRequest.java diff --git a/src/com/android/messaging/mmslib/Downloads.java b/app/src/main/java/com/android/messaging/mmslib/Downloads.java similarity index 100% rename from src/com/android/messaging/mmslib/Downloads.java rename to app/src/main/java/com/android/messaging/mmslib/Downloads.java diff --git a/src/com/android/messaging/mmslib/SqliteWrapper.java b/app/src/main/java/com/android/messaging/mmslib/SqliteWrapper.java similarity index 100% rename from src/com/android/messaging/mmslib/SqliteWrapper.java rename to app/src/main/java/com/android/messaging/mmslib/SqliteWrapper.java diff --git a/src/com/android/messaging/mmslib/pdu/PduComposer.java b/app/src/main/java/com/android/messaging/mmslib/pdu/PduComposer.java similarity index 100% rename from src/com/android/messaging/mmslib/pdu/PduComposer.java rename to app/src/main/java/com/android/messaging/mmslib/pdu/PduComposer.java diff --git a/src/com/android/messaging/mmslib/pdu/PduPersister.java b/app/src/main/java/com/android/messaging/mmslib/pdu/PduPersister.java similarity index 100% rename from src/com/android/messaging/mmslib/pdu/PduPersister.java rename to app/src/main/java/com/android/messaging/mmslib/pdu/PduPersister.java diff --git a/src/com/android/messaging/mmslib/util/AbstractCache.java b/app/src/main/java/com/android/messaging/mmslib/util/AbstractCache.java similarity index 100% rename from src/com/android/messaging/mmslib/util/AbstractCache.java rename to app/src/main/java/com/android/messaging/mmslib/util/AbstractCache.java diff --git a/src/com/android/messaging/mmslib/util/DownloadDrmHelper.java b/app/src/main/java/com/android/messaging/mmslib/util/DownloadDrmHelper.java similarity index 100% rename from src/com/android/messaging/mmslib/util/DownloadDrmHelper.java rename to app/src/main/java/com/android/messaging/mmslib/util/DownloadDrmHelper.java diff --git a/src/com/android/messaging/mmslib/util/DrmConvertSession.java b/app/src/main/java/com/android/messaging/mmslib/util/DrmConvertSession.java similarity index 100% rename from src/com/android/messaging/mmslib/util/DrmConvertSession.java rename to app/src/main/java/com/android/messaging/mmslib/util/DrmConvertSession.java diff --git a/src/com/android/messaging/mmslib/util/PduCache.java b/app/src/main/java/com/android/messaging/mmslib/util/PduCache.java similarity index 100% rename from src/com/android/messaging/mmslib/util/PduCache.java rename to app/src/main/java/com/android/messaging/mmslib/util/PduCache.java diff --git a/src/com/android/messaging/mmslib/util/PduCacheEntry.java b/app/src/main/java/com/android/messaging/mmslib/util/PduCacheEntry.java similarity index 100% rename from src/com/android/messaging/mmslib/util/PduCacheEntry.java rename to app/src/main/java/com/android/messaging/mmslib/util/PduCacheEntry.java diff --git a/src/com/android/messaging/receiver/BootAndPackageReplacedReceiver.java b/app/src/main/java/com/android/messaging/receiver/BootAndPackageReplacedReceiver.java similarity index 100% rename from src/com/android/messaging/receiver/BootAndPackageReplacedReceiver.java rename to app/src/main/java/com/android/messaging/receiver/BootAndPackageReplacedReceiver.java diff --git a/src/com/android/messaging/receiver/DefaultSmsSubscriptionChangeReceiver.java b/app/src/main/java/com/android/messaging/receiver/DefaultSmsSubscriptionChangeReceiver.java similarity index 100% rename from src/com/android/messaging/receiver/DefaultSmsSubscriptionChangeReceiver.java rename to app/src/main/java/com/android/messaging/receiver/DefaultSmsSubscriptionChangeReceiver.java diff --git a/src/com/android/messaging/receiver/MmsWapPushDeliverReceiver.java b/app/src/main/java/com/android/messaging/receiver/MmsWapPushDeliverReceiver.java similarity index 100% rename from src/com/android/messaging/receiver/MmsWapPushDeliverReceiver.java rename to app/src/main/java/com/android/messaging/receiver/MmsWapPushDeliverReceiver.java diff --git a/src/com/android/messaging/receiver/NotificationReceiver.java b/app/src/main/java/com/android/messaging/receiver/NotificationReceiver.java similarity index 100% rename from src/com/android/messaging/receiver/NotificationReceiver.java rename to app/src/main/java/com/android/messaging/receiver/NotificationReceiver.java diff --git a/src/com/android/messaging/receiver/SendStatusReceiver.java b/app/src/main/java/com/android/messaging/receiver/SendStatusReceiver.java similarity index 100% rename from src/com/android/messaging/receiver/SendStatusReceiver.java rename to app/src/main/java/com/android/messaging/receiver/SendStatusReceiver.java diff --git a/src/com/android/messaging/receiver/SmsDeliverReceiver.java b/app/src/main/java/com/android/messaging/receiver/SmsDeliverReceiver.java similarity index 100% rename from src/com/android/messaging/receiver/SmsDeliverReceiver.java rename to app/src/main/java/com/android/messaging/receiver/SmsDeliverReceiver.java diff --git a/src/com/android/messaging/receiver/SmsReceiver.java b/app/src/main/java/com/android/messaging/receiver/SmsReceiver.java similarity index 100% rename from src/com/android/messaging/receiver/SmsReceiver.java rename to app/src/main/java/com/android/messaging/receiver/SmsReceiver.java diff --git a/src/com/android/messaging/sms/ApnsXmlProcessor.java b/app/src/main/java/com/android/messaging/sms/ApnsXmlProcessor.java similarity index 100% rename from src/com/android/messaging/sms/ApnsXmlProcessor.java rename to app/src/main/java/com/android/messaging/sms/ApnsXmlProcessor.java diff --git a/src/com/android/messaging/sms/BugleApnSettingsLoader.java b/app/src/main/java/com/android/messaging/sms/BugleApnSettingsLoader.java similarity index 100% rename from src/com/android/messaging/sms/BugleApnSettingsLoader.java rename to app/src/main/java/com/android/messaging/sms/BugleApnSettingsLoader.java diff --git a/src/com/android/messaging/sms/BugleCarrierConfigValuesLoader.java b/app/src/main/java/com/android/messaging/sms/BugleCarrierConfigValuesLoader.java similarity index 100% rename from src/com/android/messaging/sms/BugleCarrierConfigValuesLoader.java rename to app/src/main/java/com/android/messaging/sms/BugleCarrierConfigValuesLoader.java diff --git a/src/com/android/messaging/sms/BugleUserAgentInfoLoader.java b/app/src/main/java/com/android/messaging/sms/BugleUserAgentInfoLoader.java similarity index 100% rename from src/com/android/messaging/sms/BugleUserAgentInfoLoader.java rename to app/src/main/java/com/android/messaging/sms/BugleUserAgentInfoLoader.java diff --git a/src/com/android/messaging/sms/DatabaseMessages.java b/app/src/main/java/com/android/messaging/sms/DatabaseMessages.java similarity index 100% rename from src/com/android/messaging/sms/DatabaseMessages.java rename to app/src/main/java/com/android/messaging/sms/DatabaseMessages.java diff --git a/src/com/android/messaging/sms/MmsConfig.java b/app/src/main/java/com/android/messaging/sms/MmsConfig.java similarity index 100% rename from src/com/android/messaging/sms/MmsConfig.java rename to app/src/main/java/com/android/messaging/sms/MmsConfig.java diff --git a/src/com/android/messaging/sms/MmsFailureException.java b/app/src/main/java/com/android/messaging/sms/MmsFailureException.java similarity index 100% rename from src/com/android/messaging/sms/MmsFailureException.java rename to app/src/main/java/com/android/messaging/sms/MmsFailureException.java diff --git a/src/com/android/messaging/sms/MmsSender.java b/app/src/main/java/com/android/messaging/sms/MmsSender.java similarity index 100% rename from src/com/android/messaging/sms/MmsSender.java rename to app/src/main/java/com/android/messaging/sms/MmsSender.java diff --git a/src/com/android/messaging/sms/MmsSmsUtils.java b/app/src/main/java/com/android/messaging/sms/MmsSmsUtils.java similarity index 100% rename from src/com/android/messaging/sms/MmsSmsUtils.java rename to app/src/main/java/com/android/messaging/sms/MmsSmsUtils.java diff --git a/src/com/android/messaging/sms/MmsUtils.java b/app/src/main/java/com/android/messaging/sms/MmsUtils.java similarity index 100% rename from src/com/android/messaging/sms/MmsUtils.java rename to app/src/main/java/com/android/messaging/sms/MmsUtils.java diff --git a/src/com/android/messaging/sms/SmsSender.java b/app/src/main/java/com/android/messaging/sms/SmsSender.java similarity index 100% rename from src/com/android/messaging/sms/SmsSender.java rename to app/src/main/java/com/android/messaging/sms/SmsSender.java diff --git a/src/com/android/messaging/ui/AsyncImageView.java b/app/src/main/java/com/android/messaging/ui/AsyncImageView.java similarity index 100% rename from src/com/android/messaging/ui/AsyncImageView.java rename to app/src/main/java/com/android/messaging/ui/AsyncImageView.java diff --git a/src/com/android/messaging/ui/AttachmentPreview.java b/app/src/main/java/com/android/messaging/ui/AttachmentPreview.java similarity index 100% rename from src/com/android/messaging/ui/AttachmentPreview.java rename to app/src/main/java/com/android/messaging/ui/AttachmentPreview.java diff --git a/src/com/android/messaging/ui/AttachmentPreviewFactory.java b/app/src/main/java/com/android/messaging/ui/AttachmentPreviewFactory.java similarity index 100% rename from src/com/android/messaging/ui/AttachmentPreviewFactory.java rename to app/src/main/java/com/android/messaging/ui/AttachmentPreviewFactory.java diff --git a/src/com/android/messaging/ui/AudioAttachmentPlayPauseButton.java b/app/src/main/java/com/android/messaging/ui/AudioAttachmentPlayPauseButton.java similarity index 100% rename from src/com/android/messaging/ui/AudioAttachmentPlayPauseButton.java rename to app/src/main/java/com/android/messaging/ui/AudioAttachmentPlayPauseButton.java diff --git a/src/com/android/messaging/ui/AudioAttachmentView.java b/app/src/main/java/com/android/messaging/ui/AudioAttachmentView.java similarity index 100% rename from src/com/android/messaging/ui/AudioAttachmentView.java rename to app/src/main/java/com/android/messaging/ui/AudioAttachmentView.java diff --git a/src/com/android/messaging/ui/AudioPlaybackProgressBar.java b/app/src/main/java/com/android/messaging/ui/AudioPlaybackProgressBar.java similarity index 100% rename from src/com/android/messaging/ui/AudioPlaybackProgressBar.java rename to app/src/main/java/com/android/messaging/ui/AudioPlaybackProgressBar.java diff --git a/src/com/android/messaging/ui/BaseBugleActivity.java b/app/src/main/java/com/android/messaging/ui/BaseBugleActivity.java similarity index 100% rename from src/com/android/messaging/ui/BaseBugleActivity.java rename to app/src/main/java/com/android/messaging/ui/BaseBugleActivity.java diff --git a/src/com/android/messaging/ui/BaseBugleFragmentActivity.java b/app/src/main/java/com/android/messaging/ui/BaseBugleFragmentActivity.java similarity index 100% rename from src/com/android/messaging/ui/BaseBugleFragmentActivity.java rename to app/src/main/java/com/android/messaging/ui/BaseBugleFragmentActivity.java diff --git a/src/com/android/messaging/ui/BasePagerViewHolder.java b/app/src/main/java/com/android/messaging/ui/BasePagerViewHolder.java similarity index 100% rename from src/com/android/messaging/ui/BasePagerViewHolder.java rename to app/src/main/java/com/android/messaging/ui/BasePagerViewHolder.java diff --git a/src/com/android/messaging/ui/BlockedParticipantListItemView.java b/app/src/main/java/com/android/messaging/ui/BlockedParticipantListItemView.java similarity index 100% rename from src/com/android/messaging/ui/BlockedParticipantListItemView.java rename to app/src/main/java/com/android/messaging/ui/BlockedParticipantListItemView.java diff --git a/src/com/android/messaging/ui/BlockedParticipantsActivity.java b/app/src/main/java/com/android/messaging/ui/BlockedParticipantsActivity.java similarity index 100% rename from src/com/android/messaging/ui/BlockedParticipantsActivity.java rename to app/src/main/java/com/android/messaging/ui/BlockedParticipantsActivity.java diff --git a/src/com/android/messaging/ui/BlockedParticipantsFragment.java b/app/src/main/java/com/android/messaging/ui/BlockedParticipantsFragment.java similarity index 100% rename from src/com/android/messaging/ui/BlockedParticipantsFragment.java rename to app/src/main/java/com/android/messaging/ui/BlockedParticipantsFragment.java diff --git a/src/com/android/messaging/ui/BugleActionBarActivity.java b/app/src/main/java/com/android/messaging/ui/BugleActionBarActivity.java similarity index 96% rename from src/com/android/messaging/ui/BugleActionBarActivity.java rename to app/src/main/java/com/android/messaging/ui/BugleActionBarActivity.java index 98d1ad5..0ee1c37 100644 --- a/src/com/android/messaging/ui/BugleActionBarActivity.java +++ b/app/src/main/java/com/android/messaging/ui/BugleActionBarActivity.java @@ -252,6 +252,11 @@ public class BugleActionBarActivity extends AppCompatActivity implements ImeUtil actionBar.setHomeAsUpIndicator(null); } + /** When false, {@link ActionMode} updates must not show the platform action bar. */ + protected boolean shouldShowContextualActionBar(final ActionMode.Callback callback) { + return true; + } + /** * Custom ActionMode implementation which allows us to just replace the contents of the main * action bar rather than overlay over it @@ -334,6 +339,10 @@ public class BugleActionBarActivity extends AppCompatActivity implements ImeUtil } public void updateActionBar(final ActionBar actionBar) { + if (!BugleActionBarActivity.this.shouldShowContextualActionBar(mCallback)) { + actionBar.hide(); + return; + } actionBar.setDisplayOptions(ActionBar.DISPLAY_HOME_AS_UP); actionBar.setDisplayShowTitleEnabled(false); actionBar.setDisplayShowCustomEnabled(false); diff --git a/src/com/android/messaging/ui/ClassZeroActivity.java b/app/src/main/java/com/android/messaging/ui/ClassZeroActivity.java similarity index 100% rename from src/com/android/messaging/ui/ClassZeroActivity.java rename to app/src/main/java/com/android/messaging/ui/ClassZeroActivity.java diff --git a/src/com/android/messaging/ui/CompositeAdapter.java b/app/src/main/java/com/android/messaging/ui/CompositeAdapter.java similarity index 100% rename from src/com/android/messaging/ui/CompositeAdapter.java rename to app/src/main/java/com/android/messaging/ui/CompositeAdapter.java diff --git a/src/com/android/messaging/ui/ContactIconView.java b/app/src/main/java/com/android/messaging/ui/ContactIconView.java similarity index 100% rename from src/com/android/messaging/ui/ContactIconView.java rename to app/src/main/java/com/android/messaging/ui/ContactIconView.java diff --git a/src/com/android/messaging/ui/ConversationDrawables.java b/app/src/main/java/com/android/messaging/ui/ConversationDrawables.java similarity index 95% rename from src/com/android/messaging/ui/ConversationDrawables.java rename to app/src/main/java/com/android/messaging/ui/ConversationDrawables.java index a9f30c4..3b1354c 100644 --- a/src/com/android/messaging/ui/ConversationDrawables.java +++ b/app/src/main/java/com/android/messaging/ui/ConversationDrawables.java @@ -49,6 +49,7 @@ public class ConversationDrawables { private Drawable mFastScrollPreviewDrawableRight; private final Context mContext; private int mOutgoingBubbleColor; + private int mIncomingBubbleColor; private int mIncomingErrorBubbleColor; private int mIncomingAudioButtonColor; private int mSelectedBubbleColor; @@ -99,6 +100,7 @@ public class ConversationDrawables { mFastScrollPreviewDrawableRight = ResourcesCompat.getDrawable(resources, R.drawable.fastscroll_preview_right, theme); mOutgoingBubbleColor = resources.getColor(R.color.message_bubble_color_outgoing, theme); + mIncomingBubbleColor = resources.getColor(R.color.message_bubble_color_incoming, theme); mIncomingErrorBubbleColor = resources.getColor(R.color.message_error_bubble_color_incoming, theme); mIncomingAudioButtonColor = @@ -124,13 +126,8 @@ public class ConversationDrawables { if (isError) { color = mIncomingErrorBubbleColor; } else { - if (identifier != null && - mContext.getResources().getBoolean(R.bool.contact_colors)) { - int idcolor = Math.abs(identifier.hashCode()) % mColors.length(); - color = mColors.getColor(idcolor, mThemeColor); - } else { - color = mThemeColor; - } + // Looply: fixed soft incoming bubble (not per-contact theme colors) + color = mIncomingBubbleColor; } } else { color = mOutgoingBubbleColor; diff --git a/src/com/android/messaging/ui/CursorRecyclerAdapter.java b/app/src/main/java/com/android/messaging/ui/CursorRecyclerAdapter.java similarity index 100% rename from src/com/android/messaging/ui/CursorRecyclerAdapter.java rename to app/src/main/java/com/android/messaging/ui/CursorRecyclerAdapter.java diff --git a/src/com/android/messaging/ui/CustomHeaderPagerListViewHolder.java b/app/src/main/java/com/android/messaging/ui/CustomHeaderPagerListViewHolder.java similarity index 100% rename from src/com/android/messaging/ui/CustomHeaderPagerListViewHolder.java rename to app/src/main/java/com/android/messaging/ui/CustomHeaderPagerListViewHolder.java diff --git a/src/com/android/messaging/ui/CustomHeaderPagerViewHolder.java b/app/src/main/java/com/android/messaging/ui/CustomHeaderPagerViewHolder.java similarity index 100% rename from src/com/android/messaging/ui/CustomHeaderPagerViewHolder.java rename to app/src/main/java/com/android/messaging/ui/CustomHeaderPagerViewHolder.java diff --git a/src/com/android/messaging/ui/CustomHeaderViewPager.java b/app/src/main/java/com/android/messaging/ui/CustomHeaderViewPager.java similarity index 100% rename from src/com/android/messaging/ui/CustomHeaderViewPager.java rename to app/src/main/java/com/android/messaging/ui/CustomHeaderViewPager.java diff --git a/src/com/android/messaging/ui/CustomHeaderViewPagerAdapter.java b/app/src/main/java/com/android/messaging/ui/CustomHeaderViewPagerAdapter.java similarity index 100% rename from src/com/android/messaging/ui/CustomHeaderViewPagerAdapter.java rename to app/src/main/java/com/android/messaging/ui/CustomHeaderViewPagerAdapter.java diff --git a/src/com/android/messaging/ui/FixedViewPagerAdapter.java b/app/src/main/java/com/android/messaging/ui/FixedViewPagerAdapter.java similarity index 100% rename from src/com/android/messaging/ui/FixedViewPagerAdapter.java rename to app/src/main/java/com/android/messaging/ui/FixedViewPagerAdapter.java diff --git a/src/com/android/messaging/ui/ImeDetectFrameLayout.java b/app/src/main/java/com/android/messaging/ui/ImeDetectFrameLayout.java similarity index 100% rename from src/com/android/messaging/ui/ImeDetectFrameLayout.java rename to app/src/main/java/com/android/messaging/ui/ImeDetectFrameLayout.java diff --git a/src/com/android/messaging/ui/LicenseActivity.java b/app/src/main/java/com/android/messaging/ui/LicenseActivity.java similarity index 100% rename from src/com/android/messaging/ui/LicenseActivity.java rename to app/src/main/java/com/android/messaging/ui/LicenseActivity.java diff --git a/src/com/android/messaging/ui/LineWrapLayout.java b/app/src/main/java/com/android/messaging/ui/LineWrapLayout.java similarity index 100% rename from src/com/android/messaging/ui/LineWrapLayout.java rename to app/src/main/java/com/android/messaging/ui/LineWrapLayout.java diff --git a/src/com/android/messaging/ui/ListEmptyView.java b/app/src/main/java/com/android/messaging/ui/ListEmptyView.java similarity index 100% rename from src/com/android/messaging/ui/ListEmptyView.java rename to app/src/main/java/com/android/messaging/ui/ListEmptyView.java diff --git a/src/com/android/messaging/ui/MaxHeightScrollView.java b/app/src/main/java/com/android/messaging/ui/MaxHeightScrollView.java similarity index 100% rename from src/com/android/messaging/ui/MaxHeightScrollView.java rename to app/src/main/java/com/android/messaging/ui/MaxHeightScrollView.java diff --git a/src/com/android/messaging/ui/MultiAttachmentLayout.java b/app/src/main/java/com/android/messaging/ui/MultiAttachmentLayout.java similarity index 100% rename from src/com/android/messaging/ui/MultiAttachmentLayout.java rename to app/src/main/java/com/android/messaging/ui/MultiAttachmentLayout.java diff --git a/src/com/android/messaging/ui/OrientedBitmapDrawable.java b/app/src/main/java/com/android/messaging/ui/OrientedBitmapDrawable.java similarity index 100% rename from src/com/android/messaging/ui/OrientedBitmapDrawable.java rename to app/src/main/java/com/android/messaging/ui/OrientedBitmapDrawable.java diff --git a/src/com/android/messaging/ui/PagerViewHolder.java b/app/src/main/java/com/android/messaging/ui/PagerViewHolder.java similarity index 100% rename from src/com/android/messaging/ui/PagerViewHolder.java rename to app/src/main/java/com/android/messaging/ui/PagerViewHolder.java diff --git a/src/com/android/messaging/ui/PagingAwareViewPager.java b/app/src/main/java/com/android/messaging/ui/PagingAwareViewPager.java similarity index 100% rename from src/com/android/messaging/ui/PagingAwareViewPager.java rename to app/src/main/java/com/android/messaging/ui/PagingAwareViewPager.java diff --git a/src/com/android/messaging/ui/PermissionCheckActivity.java b/app/src/main/java/com/android/messaging/ui/PermissionCheckActivity.java similarity index 100% rename from src/com/android/messaging/ui/PermissionCheckActivity.java rename to app/src/main/java/com/android/messaging/ui/PermissionCheckActivity.java diff --git a/src/com/android/messaging/ui/PersistentInstanceState.java b/app/src/main/java/com/android/messaging/ui/PersistentInstanceState.java similarity index 100% rename from src/com/android/messaging/ui/PersistentInstanceState.java rename to app/src/main/java/com/android/messaging/ui/PersistentInstanceState.java diff --git a/src/com/android/messaging/ui/PersonItemView.java b/app/src/main/java/com/android/messaging/ui/PersonItemView.java similarity index 100% rename from src/com/android/messaging/ui/PersonItemView.java rename to app/src/main/java/com/android/messaging/ui/PersonItemView.java diff --git a/src/com/android/messaging/ui/PlaceholderInsetDrawable.java b/app/src/main/java/com/android/messaging/ui/PlaceholderInsetDrawable.java similarity index 100% rename from src/com/android/messaging/ui/PlaceholderInsetDrawable.java rename to app/src/main/java/com/android/messaging/ui/PlaceholderInsetDrawable.java diff --git a/src/com/android/messaging/ui/PlainTextEditText.java b/app/src/main/java/com/android/messaging/ui/PlainTextEditText.java similarity index 100% rename from src/com/android/messaging/ui/PlainTextEditText.java rename to app/src/main/java/com/android/messaging/ui/PlainTextEditText.java diff --git a/src/com/android/messaging/ui/PlaybackStateView.java b/app/src/main/java/com/android/messaging/ui/PlaybackStateView.java similarity index 100% rename from src/com/android/messaging/ui/PlaybackStateView.java rename to app/src/main/java/com/android/messaging/ui/PlaybackStateView.java diff --git a/src/com/android/messaging/ui/RemoteInputEntrypointActivity.java b/app/src/main/java/com/android/messaging/ui/RemoteInputEntrypointActivity.java similarity index 100% rename from src/com/android/messaging/ui/RemoteInputEntrypointActivity.java rename to app/src/main/java/com/android/messaging/ui/RemoteInputEntrypointActivity.java diff --git a/src/com/android/messaging/ui/SnackBar.java b/app/src/main/java/com/android/messaging/ui/SnackBar.java similarity index 100% rename from src/com/android/messaging/ui/SnackBar.java rename to app/src/main/java/com/android/messaging/ui/SnackBar.java diff --git a/src/com/android/messaging/ui/SnackBarInteraction.java b/app/src/main/java/com/android/messaging/ui/SnackBarInteraction.java similarity index 100% rename from src/com/android/messaging/ui/SnackBarInteraction.java rename to app/src/main/java/com/android/messaging/ui/SnackBarInteraction.java diff --git a/src/com/android/messaging/ui/SnackBarManager.java b/app/src/main/java/com/android/messaging/ui/SnackBarManager.java similarity index 100% rename from src/com/android/messaging/ui/SnackBarManager.java rename to app/src/main/java/com/android/messaging/ui/SnackBarManager.java diff --git a/src/com/android/messaging/ui/UIIntents.java b/app/src/main/java/com/android/messaging/ui/UIIntents.java similarity index 100% rename from src/com/android/messaging/ui/UIIntents.java rename to app/src/main/java/com/android/messaging/ui/UIIntents.java diff --git a/src/com/android/messaging/ui/UIIntentsImpl.java b/app/src/main/java/com/android/messaging/ui/UIIntentsImpl.java similarity index 100% rename from src/com/android/messaging/ui/UIIntentsImpl.java rename to app/src/main/java/com/android/messaging/ui/UIIntentsImpl.java diff --git a/src/com/android/messaging/ui/VCardDetailActivity.java b/app/src/main/java/com/android/messaging/ui/VCardDetailActivity.java similarity index 100% rename from src/com/android/messaging/ui/VCardDetailActivity.java rename to app/src/main/java/com/android/messaging/ui/VCardDetailActivity.java diff --git a/src/com/android/messaging/ui/VCardDetailAdapter.java b/app/src/main/java/com/android/messaging/ui/VCardDetailAdapter.java similarity index 100% rename from src/com/android/messaging/ui/VCardDetailAdapter.java rename to app/src/main/java/com/android/messaging/ui/VCardDetailAdapter.java diff --git a/src/com/android/messaging/ui/VCardDetailFragment.java b/app/src/main/java/com/android/messaging/ui/VCardDetailFragment.java similarity index 100% rename from src/com/android/messaging/ui/VCardDetailFragment.java rename to app/src/main/java/com/android/messaging/ui/VCardDetailFragment.java diff --git a/src/com/android/messaging/ui/VideoThumbnailView.java b/app/src/main/java/com/android/messaging/ui/VideoThumbnailView.java similarity index 100% rename from src/com/android/messaging/ui/VideoThumbnailView.java rename to app/src/main/java/com/android/messaging/ui/VideoThumbnailView.java diff --git a/src/com/android/messaging/ui/ViewPagerTabStrip.java b/app/src/main/java/com/android/messaging/ui/ViewPagerTabStrip.java similarity index 100% rename from src/com/android/messaging/ui/ViewPagerTabStrip.java rename to app/src/main/java/com/android/messaging/ui/ViewPagerTabStrip.java diff --git a/src/com/android/messaging/ui/ViewPagerTabs.java b/app/src/main/java/com/android/messaging/ui/ViewPagerTabs.java similarity index 100% rename from src/com/android/messaging/ui/ViewPagerTabs.java rename to app/src/main/java/com/android/messaging/ui/ViewPagerTabs.java diff --git a/src/com/android/messaging/ui/WidgetPickConversationActivity.java b/app/src/main/java/com/android/messaging/ui/WidgetPickConversationActivity.java similarity index 100% rename from src/com/android/messaging/ui/WidgetPickConversationActivity.java rename to app/src/main/java/com/android/messaging/ui/WidgetPickConversationActivity.java diff --git a/src/com/android/messaging/ui/animation/PopupTransitionAnimation.java b/app/src/main/java/com/android/messaging/ui/animation/PopupTransitionAnimation.java similarity index 100% rename from src/com/android/messaging/ui/animation/PopupTransitionAnimation.java rename to app/src/main/java/com/android/messaging/ui/animation/PopupTransitionAnimation.java diff --git a/src/com/android/messaging/ui/animation/RectEvaluatorCompat.java b/app/src/main/java/com/android/messaging/ui/animation/RectEvaluatorCompat.java similarity index 100% rename from src/com/android/messaging/ui/animation/RectEvaluatorCompat.java rename to app/src/main/java/com/android/messaging/ui/animation/RectEvaluatorCompat.java diff --git a/src/com/android/messaging/ui/animation/ViewGroupItemVerticalExplodeAnimation.java b/app/src/main/java/com/android/messaging/ui/animation/ViewGroupItemVerticalExplodeAnimation.java similarity index 100% rename from src/com/android/messaging/ui/animation/ViewGroupItemVerticalExplodeAnimation.java rename to app/src/main/java/com/android/messaging/ui/animation/ViewGroupItemVerticalExplodeAnimation.java diff --git a/src/com/android/messaging/ui/appsettings/ApplicationSettingsActivity.java b/app/src/main/java/com/android/messaging/ui/appsettings/ApplicationSettingsActivity.java similarity index 100% rename from src/com/android/messaging/ui/appsettings/ApplicationSettingsActivity.java rename to app/src/main/java/com/android/messaging/ui/appsettings/ApplicationSettingsActivity.java diff --git a/src/com/android/messaging/ui/appsettings/GroupMmsSettingDialog.java b/app/src/main/java/com/android/messaging/ui/appsettings/GroupMmsSettingDialog.java similarity index 100% rename from src/com/android/messaging/ui/appsettings/GroupMmsSettingDialog.java rename to app/src/main/java/com/android/messaging/ui/appsettings/GroupMmsSettingDialog.java diff --git a/src/com/android/messaging/ui/appsettings/PerSubscriptionSettingsActivity.java b/app/src/main/java/com/android/messaging/ui/appsettings/PerSubscriptionSettingsActivity.java similarity index 100% rename from src/com/android/messaging/ui/appsettings/PerSubscriptionSettingsActivity.java rename to app/src/main/java/com/android/messaging/ui/appsettings/PerSubscriptionSettingsActivity.java diff --git a/src/com/android/messaging/ui/appsettings/PhoneNumberPreference.java b/app/src/main/java/com/android/messaging/ui/appsettings/PhoneNumberPreference.java similarity index 100% rename from src/com/android/messaging/ui/appsettings/PhoneNumberPreference.java rename to app/src/main/java/com/android/messaging/ui/appsettings/PhoneNumberPreference.java diff --git a/src/com/android/messaging/ui/appsettings/SettingsActivity.java b/app/src/main/java/com/android/messaging/ui/appsettings/SettingsActivity.java similarity index 100% rename from src/com/android/messaging/ui/appsettings/SettingsActivity.java rename to app/src/main/java/com/android/messaging/ui/appsettings/SettingsActivity.java diff --git a/src/com/android/messaging/ui/attachmentchooser/AttachmentChooserActivity.java b/app/src/main/java/com/android/messaging/ui/attachmentchooser/AttachmentChooserActivity.java similarity index 100% rename from src/com/android/messaging/ui/attachmentchooser/AttachmentChooserActivity.java rename to app/src/main/java/com/android/messaging/ui/attachmentchooser/AttachmentChooserActivity.java diff --git a/src/com/android/messaging/ui/attachmentchooser/AttachmentChooserFragment.java b/app/src/main/java/com/android/messaging/ui/attachmentchooser/AttachmentChooserFragment.java similarity index 100% rename from src/com/android/messaging/ui/attachmentchooser/AttachmentChooserFragment.java rename to app/src/main/java/com/android/messaging/ui/attachmentchooser/AttachmentChooserFragment.java diff --git a/src/com/android/messaging/ui/attachmentchooser/AttachmentGridItemView.java b/app/src/main/java/com/android/messaging/ui/attachmentchooser/AttachmentGridItemView.java similarity index 100% rename from src/com/android/messaging/ui/attachmentchooser/AttachmentGridItemView.java rename to app/src/main/java/com/android/messaging/ui/attachmentchooser/AttachmentGridItemView.java diff --git a/src/com/android/messaging/ui/attachmentchooser/AttachmentGridView.java b/app/src/main/java/com/android/messaging/ui/attachmentchooser/AttachmentGridView.java similarity index 100% rename from src/com/android/messaging/ui/attachmentchooser/AttachmentGridView.java rename to app/src/main/java/com/android/messaging/ui/attachmentchooser/AttachmentGridView.java diff --git a/src/com/android/messaging/ui/contact/AddContactsConfirmationDialog.java b/app/src/main/java/com/android/messaging/ui/contact/AddContactsConfirmationDialog.java similarity index 100% rename from src/com/android/messaging/ui/contact/AddContactsConfirmationDialog.java rename to app/src/main/java/com/android/messaging/ui/contact/AddContactsConfirmationDialog.java diff --git a/src/com/android/messaging/ui/contact/AllContactsListViewHolder.java b/app/src/main/java/com/android/messaging/ui/contact/AllContactsListViewHolder.java similarity index 100% rename from src/com/android/messaging/ui/contact/AllContactsListViewHolder.java rename to app/src/main/java/com/android/messaging/ui/contact/AllContactsListViewHolder.java diff --git a/src/com/android/messaging/ui/contact/ContactDropdownLayouter.java b/app/src/main/java/com/android/messaging/ui/contact/ContactDropdownLayouter.java similarity index 100% rename from src/com/android/messaging/ui/contact/ContactDropdownLayouter.java rename to app/src/main/java/com/android/messaging/ui/contact/ContactDropdownLayouter.java diff --git a/src/com/android/messaging/ui/contact/ContactListAdapter.java b/app/src/main/java/com/android/messaging/ui/contact/ContactListAdapter.java similarity index 100% rename from src/com/android/messaging/ui/contact/ContactListAdapter.java rename to app/src/main/java/com/android/messaging/ui/contact/ContactListAdapter.java diff --git a/src/com/android/messaging/ui/contact/ContactListItemView.java b/app/src/main/java/com/android/messaging/ui/contact/ContactListItemView.java similarity index 100% rename from src/com/android/messaging/ui/contact/ContactListItemView.java rename to app/src/main/java/com/android/messaging/ui/contact/ContactListItemView.java diff --git a/src/com/android/messaging/ui/contact/ContactPickerFragment.java b/app/src/main/java/com/android/messaging/ui/contact/ContactPickerFragment.java similarity index 97% rename from src/com/android/messaging/ui/contact/ContactPickerFragment.java rename to app/src/main/java/com/android/messaging/ui/contact/ContactPickerFragment.java index 66162bf..61b39a4 100644 --- a/src/com/android/messaging/ui/contact/ContactPickerFragment.java +++ b/app/src/main/java/com/android/messaging/ui/contact/ContactPickerFragment.java @@ -182,12 +182,22 @@ public class ContactPickerFragment extends Fragment implements ContactPickerData mCustomHeaderViewPager.setCurrentItem(0); mToolbar = view.findViewById(R.id.toolbar); - mToolbar.setNavigationIcon(R.drawable.ic_arrow_back_light); + mToolbar.setNavigationIcon(R.drawable.ic_looply_back); mToolbar.setNavigationContentDescription(R.string.back); mToolbar.setNavigationOnClickListener(v -> mHost.onBackButtonPressed()); + mToolbar.setTitle(null); mToolbar.inflateMenu(R.menu.compose_menu); mToolbar.setOnMenuItemClickListener(this); + final int iconTint = getResources().getColor(R.color.looply_primary, + requireActivity().getTheme()); + final Menu toolbarMenu = mToolbar.getMenu(); + for (int i = 0; i < toolbarMenu.size(); i++) { + final android.graphics.drawable.Drawable icon = toolbarMenu.getItem(i).getIcon(); + if (icon != null) { + icon.mutate().setTint(iconTint); + } + } mComposeDivider = view.findViewById(R.id.compose_contact_divider); mRootView = view; @@ -547,8 +557,7 @@ public class ContactPickerFragment extends Fragment implements ContactPickerData // etc. will take the spot of the action bar. actionBar.hide(); UiUtils.setStatusBarColor(getActivity(), - getResources().getColor(R.color.compose_notification_bar_background, - getActivity().getTheme())); + getResources().getColor(R.color.looply_bg, getActivity().getTheme())); } private GetOrCreateConversationActionMonitor mMonitor; diff --git a/src/com/android/messaging/ui/contact/ContactRecipientAdapter.java b/app/src/main/java/com/android/messaging/ui/contact/ContactRecipientAdapter.java similarity index 100% rename from src/com/android/messaging/ui/contact/ContactRecipientAdapter.java rename to app/src/main/java/com/android/messaging/ui/contact/ContactRecipientAdapter.java diff --git a/src/com/android/messaging/ui/contact/ContactRecipientAutoCompleteView.java b/app/src/main/java/com/android/messaging/ui/contact/ContactRecipientAutoCompleteView.java similarity index 100% rename from src/com/android/messaging/ui/contact/ContactRecipientAutoCompleteView.java rename to app/src/main/java/com/android/messaging/ui/contact/ContactRecipientAutoCompleteView.java diff --git a/src/com/android/messaging/ui/contact/ContactRecipientPhotoManager.java b/app/src/main/java/com/android/messaging/ui/contact/ContactRecipientPhotoManager.java similarity index 100% rename from src/com/android/messaging/ui/contact/ContactRecipientPhotoManager.java rename to app/src/main/java/com/android/messaging/ui/contact/ContactRecipientPhotoManager.java diff --git a/src/com/android/messaging/ui/contact/ContactSectionIndexer.java b/app/src/main/java/com/android/messaging/ui/contact/ContactSectionIndexer.java similarity index 100% rename from src/com/android/messaging/ui/contact/ContactSectionIndexer.java rename to app/src/main/java/com/android/messaging/ui/contact/ContactSectionIndexer.java diff --git a/src/com/android/messaging/ui/contact/FrequentContactsListViewHolder.java b/app/src/main/java/com/android/messaging/ui/contact/FrequentContactsListViewHolder.java similarity index 100% rename from src/com/android/messaging/ui/contact/FrequentContactsListViewHolder.java rename to app/src/main/java/com/android/messaging/ui/contact/FrequentContactsListViewHolder.java diff --git a/src/com/android/messaging/ui/conversation/ComposeMessageView.java b/app/src/main/java/com/android/messaging/ui/conversation/ComposeMessageView.java similarity index 100% rename from src/com/android/messaging/ui/conversation/ComposeMessageView.java rename to app/src/main/java/com/android/messaging/ui/conversation/ComposeMessageView.java diff --git a/src/com/android/messaging/ui/conversation/ConversationActivity.java b/app/src/main/java/com/android/messaging/ui/conversation/ConversationActivity.java similarity index 100% rename from src/com/android/messaging/ui/conversation/ConversationActivity.java rename to app/src/main/java/com/android/messaging/ui/conversation/ConversationActivity.java diff --git a/src/com/android/messaging/ui/conversation/ConversationActivityUiState.java b/app/src/main/java/com/android/messaging/ui/conversation/ConversationActivityUiState.java similarity index 100% rename from src/com/android/messaging/ui/conversation/ConversationActivityUiState.java rename to app/src/main/java/com/android/messaging/ui/conversation/ConversationActivityUiState.java diff --git a/src/com/android/messaging/ui/conversation/ConversationFastScroller.java b/app/src/main/java/com/android/messaging/ui/conversation/ConversationFastScroller.java similarity index 100% rename from src/com/android/messaging/ui/conversation/ConversationFastScroller.java rename to app/src/main/java/com/android/messaging/ui/conversation/ConversationFastScroller.java diff --git a/src/com/android/messaging/ui/conversation/ConversationFragment.java b/app/src/main/java/com/android/messaging/ui/conversation/ConversationFragment.java similarity index 100% rename from src/com/android/messaging/ui/conversation/ConversationFragment.java rename to app/src/main/java/com/android/messaging/ui/conversation/ConversationFragment.java diff --git a/src/com/android/messaging/ui/conversation/ConversationInput.java b/app/src/main/java/com/android/messaging/ui/conversation/ConversationInput.java similarity index 100% rename from src/com/android/messaging/ui/conversation/ConversationInput.java rename to app/src/main/java/com/android/messaging/ui/conversation/ConversationInput.java diff --git a/src/com/android/messaging/ui/conversation/ConversationInputManager.java b/app/src/main/java/com/android/messaging/ui/conversation/ConversationInputManager.java similarity index 100% rename from src/com/android/messaging/ui/conversation/ConversationInputManager.java rename to app/src/main/java/com/android/messaging/ui/conversation/ConversationInputManager.java diff --git a/src/com/android/messaging/ui/conversation/ConversationMessageAdapter.java b/app/src/main/java/com/android/messaging/ui/conversation/ConversationMessageAdapter.java similarity index 100% rename from src/com/android/messaging/ui/conversation/ConversationMessageAdapter.java rename to app/src/main/java/com/android/messaging/ui/conversation/ConversationMessageAdapter.java diff --git a/src/com/android/messaging/ui/conversation/ConversationMessageBubbleView.java b/app/src/main/java/com/android/messaging/ui/conversation/ConversationMessageBubbleView.java similarity index 100% rename from src/com/android/messaging/ui/conversation/ConversationMessageBubbleView.java rename to app/src/main/java/com/android/messaging/ui/conversation/ConversationMessageBubbleView.java diff --git a/src/com/android/messaging/ui/conversation/ConversationMessageView.java b/app/src/main/java/com/android/messaging/ui/conversation/ConversationMessageView.java similarity index 100% rename from src/com/android/messaging/ui/conversation/ConversationMessageView.java rename to app/src/main/java/com/android/messaging/ui/conversation/ConversationMessageView.java diff --git a/src/com/android/messaging/ui/conversation/ConversationSimSelector.java b/app/src/main/java/com/android/messaging/ui/conversation/ConversationSimSelector.java similarity index 100% rename from src/com/android/messaging/ui/conversation/ConversationSimSelector.java rename to app/src/main/java/com/android/messaging/ui/conversation/ConversationSimSelector.java diff --git a/src/com/android/messaging/ui/conversation/EnterSelfPhoneNumberDialog.java b/app/src/main/java/com/android/messaging/ui/conversation/EnterSelfPhoneNumberDialog.java similarity index 100% rename from src/com/android/messaging/ui/conversation/EnterSelfPhoneNumberDialog.java rename to app/src/main/java/com/android/messaging/ui/conversation/EnterSelfPhoneNumberDialog.java diff --git a/src/com/android/messaging/ui/conversation/LaunchConversationActivity.java b/app/src/main/java/com/android/messaging/ui/conversation/LaunchConversationActivity.java similarity index 100% rename from src/com/android/messaging/ui/conversation/LaunchConversationActivity.java rename to app/src/main/java/com/android/messaging/ui/conversation/LaunchConversationActivity.java diff --git a/src/com/android/messaging/ui/conversation/MessageBubbleBackground.java b/app/src/main/java/com/android/messaging/ui/conversation/MessageBubbleBackground.java similarity index 100% rename from src/com/android/messaging/ui/conversation/MessageBubbleBackground.java rename to app/src/main/java/com/android/messaging/ui/conversation/MessageBubbleBackground.java diff --git a/src/com/android/messaging/ui/conversation/MessageDetailsDialog.java b/app/src/main/java/com/android/messaging/ui/conversation/MessageDetailsDialog.java similarity index 100% rename from src/com/android/messaging/ui/conversation/MessageDetailsDialog.java rename to app/src/main/java/com/android/messaging/ui/conversation/MessageDetailsDialog.java diff --git a/src/com/android/messaging/ui/conversation/SimIconView.java b/app/src/main/java/com/android/messaging/ui/conversation/SimIconView.java similarity index 100% rename from src/com/android/messaging/ui/conversation/SimIconView.java rename to app/src/main/java/com/android/messaging/ui/conversation/SimIconView.java diff --git a/src/com/android/messaging/ui/conversation/SimSelectorItemView.java b/app/src/main/java/com/android/messaging/ui/conversation/SimSelectorItemView.java similarity index 100% rename from src/com/android/messaging/ui/conversation/SimSelectorItemView.java rename to app/src/main/java/com/android/messaging/ui/conversation/SimSelectorItemView.java diff --git a/src/com/android/messaging/ui/conversation/SimSelectorView.java b/app/src/main/java/com/android/messaging/ui/conversation/SimSelectorView.java similarity index 100% rename from src/com/android/messaging/ui/conversation/SimSelectorView.java rename to app/src/main/java/com/android/messaging/ui/conversation/SimSelectorView.java diff --git a/src/com/android/messaging/ui/conversationlist/AbstractConversationListActivity.java b/app/src/main/java/com/android/messaging/ui/conversationlist/AbstractConversationListActivity.java similarity index 91% rename from src/com/android/messaging/ui/conversationlist/AbstractConversationListActivity.java rename to app/src/main/java/com/android/messaging/ui/conversationlist/AbstractConversationListActivity.java index 809a364..ecc97f7 100644 --- a/src/com/android/messaging/ui/conversationlist/AbstractConversationListActivity.java +++ b/app/src/main/java/com/android/messaging/ui/conversationlist/AbstractConversationListActivity.java @@ -31,6 +31,7 @@ import androidx.activity.result.ActivityResultLauncher; import androidx.activity.result.contract.ActivityResultContracts; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.appcompat.app.ActionBar; import com.android.messaging.R; import com.android.messaging.datamodel.action.DeleteConversationAction; @@ -85,17 +86,44 @@ public abstract class AbstractConversationListActivity extends BugleActionBarAct super.onBackPressed(); } - protected void startMultiSelectActionMode() { - startActionMode(new MultiSelectActionModeCallback(this)); - mConversationListFragment.dismissFab(); + protected boolean useHomeSelectionChrome() { + return false; } - protected void exitMultiSelectState() { + protected void startMultiSelectActionMode() { + startActionMode(new MultiSelectActionModeCallback(this, useHomeSelectionChrome())); + mConversationListFragment.dismissFab(); + if (useHomeSelectionChrome()) { + mConversationListFragment.setHomeSelectionMode(true); + hideHomeContextualActionBar(); + } + } + + public void exitMultiSelectState() { + if (useHomeSelectionChrome()) { + mConversationListFragment.setHomeSelectionMode(false); + } mConversationListFragment.showFab(); dismissActionMode(); mConversationListFragment.updateUi(); } + protected void hideHomeContextualActionBar() { + final ActionBar actionBar = getSupportActionBar(); + if (actionBar != null) { + actionBar.hide(); + } + } + + public void deleteSelectedConversations() { + if (!isInConversationListSelectMode()) { + return; + } + final MultiSelectActionModeCallback callback = + (MultiSelectActionModeCallback) getActionModeCallback(); + onActionBarDelete(callback.getSelectedConversations()); + } + protected boolean isInConversationListSelectMode() { return getActionModeCallback() instanceof MultiSelectActionModeCallback; } @@ -225,6 +253,14 @@ public abstract class AbstractConversationListActivity extends BugleActionBarAct .show(); } + @Override + public void onSelectionCountChanged(final int count) { + if (useHomeSelectionChrome()) { + mConversationListFragment.updateHomeSelectionDeleteEnabled(count); + hideHomeContextualActionBar(); + } + } + @Override public void onConversationClick(final ConversationListData listData, final ConversationListItemData conversationListItemData, diff --git a/src/com/android/messaging/ui/conversationlist/ArchivedConversationListActivity.java b/app/src/main/java/com/android/messaging/ui/conversationlist/ArchivedConversationListActivity.java similarity index 100% rename from src/com/android/messaging/ui/conversationlist/ArchivedConversationListActivity.java rename to app/src/main/java/com/android/messaging/ui/conversationlist/ArchivedConversationListActivity.java diff --git a/src/com/android/messaging/ui/conversationlist/ConversationListActivity.java b/app/src/main/java/com/android/messaging/ui/conversationlist/ConversationListActivity.java similarity index 73% rename from src/com/android/messaging/ui/conversationlist/ConversationListActivity.java rename to app/src/main/java/com/android/messaging/ui/conversationlist/ConversationListActivity.java index d20173c..799abc3 100644 --- a/src/com/android/messaging/ui/conversationlist/ConversationListActivity.java +++ b/app/src/main/java/com/android/messaging/ui/conversationlist/ConversationListActivity.java @@ -17,13 +17,15 @@ package com.android.messaging.ui.conversationlist; -import android.graphics.drawable.ColorDrawable; import android.os.Bundle; +import android.view.ActionMode; import android.view.Menu; import android.view.MenuItem; +import android.widget.Toast; import androidx.annotation.NonNull; import androidx.appcompat.app.ActionBar; +import androidx.appcompat.widget.PopupMenu; import com.android.messaging.R; import com.android.messaging.ui.UIIntents; @@ -45,24 +47,32 @@ public class ConversationListActivity extends AbstractConversationListActivity { invalidateActionBar(); } + @Override + protected boolean useHomeSelectionChrome() { + return true; + } + + @Override + protected boolean shouldShowContextualActionBar(final ActionMode.Callback callback) { + if (callback instanceof MultiSelectActionModeCallback) { + return !((MultiSelectActionModeCallback) callback).useHomeSelectionChrome(); + } + return true; + } + @Override protected void updateActionBar(final ActionBar actionBar) { - actionBar.setTitle(getString(R.string.app_name)); - actionBar.setDisplayShowTitleEnabled(true); - actionBar.setDisplayHomeAsUpEnabled(false); - actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD); - actionBar.setBackgroundDrawable(new ColorDrawable( - getResources().getColor(R.color.action_bar_background_color))); - actionBar.show(); + if (actionBar == null) { + return; + } + // Custom Message+ chrome replaces the ActionBar on the home screen. + actionBar.hide(); super.updateActionBar(actionBar); } @Override public void onResume() { super.onResume(); - // Invalidate the menu as items that are based on settings may have changed - // while not in the app (e.g. Talkback enabled/disable affects new conversation - // button) supportInvalidateOptionsMenu(); } @@ -124,6 +134,27 @@ public class ConversationListActivity extends AbstractConversationListActivity { UIIntents.get().launchArchivedConversationsActivity(this); } + public void showHomeOverflowMenu(final android.view.View anchor) { + final PopupMenu popup = new PopupMenu(this, anchor); + popup.getMenuInflater().inflate(R.menu.conversation_list_fragment_menu, popup.getMenu()); + final MenuItem startNew = popup.getMenu().findItem(R.id.action_start_new_conversation); + if (startNew != null) { + startNew.setVisible(false); + } + popup.setOnMenuItemClickListener(this::onOptionsItemSelected); + popup.show(); + } + + public void showAutomateComingSoon() { + Toast.makeText(this, R.string.home_automate_coming_soon, Toast.LENGTH_SHORT).show(); + } + + public void enterHomeEditMode() { + if (!isInConversationListSelectMode()) { + startMultiSelectActionMode(); + } + } + @Override public boolean isSwipeAnimatable() { return !isInConversationListSelectMode(); @@ -132,8 +163,6 @@ public class ConversationListActivity extends AbstractConversationListActivity { @Override public void onWindowFocusChanged(final boolean hasFocus) { super.onWindowFocusChanged(hasFocus); - // When the screen is turned on, the last used activity gets resumed, but it gets - // window focus only after the lock screen is unlocked. if (hasFocus && mConversationListFragment != null) { mConversationListFragment.setScrolledToNewestConversationIfNeeded(); } diff --git a/app/src/main/java/com/android/messaging/ui/conversationlist/ConversationListAdapter.java b/app/src/main/java/com/android/messaging/ui/conversationlist/ConversationListAdapter.java new file mode 100644 index 0000000..10d9ba6 --- /dev/null +++ b/app/src/main/java/com/android/messaging/ui/conversationlist/ConversationListAdapter.java @@ -0,0 +1,442 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * Copyright (C) 2024 The LineageOS Project + + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + + * http://www.apache.org/licenses/LICENSE-2.0 + + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.messaging.ui.conversationlist; + +import android.content.Context; +import android.database.Cursor; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.FrameLayout; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.DiffUtil; +import androidx.recyclerview.widget.ListUpdateCallback; +import androidx.recyclerview.widget.RecyclerView; + +import com.android.messaging.R; +import com.android.messaging.datamodel.data.ConversationListItemData; +import com.android.messaging.ui.CursorRecyclerAdapter; +import com.android.messaging.ui.home.PinnedConversationStore; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.function.Consumer; + +/** + * Provides an interface to expose Conversation List Cursor data to a UI widget like a ListView. + */ +public class ConversationListAdapter + extends CursorRecyclerAdapter { + + public static final int FILTER_ALL = 0; + public static final int FILTER_UNREAD = 1; + public static final int FILTER_GROUPS = 2; + + private static final int VIEW_TYPE_PINNED_HEADER = 1; + private static final int VIEW_TYPE_CONVERSATION = 2; + private static final long PINNED_HEADER_ITEM_ID = -9001L; + + private final ConversationListItemView.HostInterface mClivHostInterface; + private final ConversationListItemData mFilterProbe = new ConversationListItemData(); + private int mFilterMode = FILTER_ALL; + private int[] mDisplayPositions = new int[0]; + private View mPinnedStripRoot; + private boolean mPinnedHeaderVisible; + + public ConversationListAdapter(final Context context, final Cursor cursor, + final ConversationListItemView.HostInterface clivHostInterface) { + super(context, cursor, 0); + mClivHostInterface = clivHostInterface; + setHasStableIds(true); + } + + public void setPinnedStripRoot(final View pinnedStripRoot) { + mPinnedStripRoot = pinnedStripRoot; + } + + public void setPinnedHeaderVisible(final boolean visible) { + if (mPinnedHeaderVisible == visible) { + return; + } + mPinnedHeaderVisible = visible; + notifyDataSetChanged(); + } + + public boolean hasPinnedHeader() { + return mPinnedHeaderVisible && mPinnedStripRoot != null; + } + + public int getPinnedHeaderOffset() { + return hasPinnedHeader() ? 1 : 0; + } + + public int getFirstConversationAdapterPosition() { + return getPinnedHeaderOffset(); + } + + public int getConversationItemCount() { + if (getCursor() == null) { + return 0; + } + return mDisplayPositions.length; + } + + public void setFilterMode(final int filterMode) { + if (mFilterMode == filterMode) { + return; + } + mFilterMode = filterMode; + rebuildFilterIndex(); + notifyDataSetChanged(); + } + + public int getFilterMode() { + return mFilterMode; + } + + public void refreshPinOrdering() { + refreshPinOrderingAnimated(); + } + + /** Re-sorts pinned rows and animates list moves when order changes. */ + public void refreshPinOrderingAnimated() { + final List oldIds = getDisplayConversationIds(); + rebuildFilterIndex(); + final List newIds = getDisplayConversationIds(); + if (oldIds.equals(newIds)) { + if (!newIds.isEmpty()) { + notifyItemRangeChanged(getPinnedHeaderOffset(), newIds.size()); + } + return; + } + final int offset = getPinnedHeaderOffset(); + DiffUtil.calculateDiff(new DiffUtil.Callback() { + @Override + public int getOldListSize() { + return oldIds.size(); + } + + @Override + public int getNewListSize() { + return newIds.size(); + } + + @Override + public boolean areItemsTheSame(final int oldItemPosition, + final int newItemPosition) { + return oldIds.get(oldItemPosition).equals(newIds.get(newItemPosition)); + } + + @Override + public boolean areContentsTheSame(final int oldItemPosition, + final int newItemPosition) { + return areItemsTheSame(oldItemPosition, newItemPosition); + } + }).dispatchUpdatesTo(new OffsetListUpdateCallback(this, offset)); + } + + public int getDisplayIndexForConversationId(final String conversationId) { + if (conversationId == null) { + return -1; + } + final List ids = getDisplayConversationIds(); + return ids.indexOf(conversationId); + } + + public int getAdapterPositionForConversationId(final String conversationId) { + final int displayIndex = getDisplayIndexForConversationId(conversationId); + if (displayIndex < 0) { + return -1; + } + return displayIndex + getPinnedHeaderOffset(); + } + + private List getDisplayConversationIds() { + final Cursor cursor = getCursor(); + if (cursor == null || mDisplayPositions.length == 0) { + return Collections.emptyList(); + } + final List ids = new ArrayList<>(mDisplayPositions.length); + final int saved = cursor.getPosition(); + for (final int position : mDisplayPositions) { + if (cursor.moveToPosition(position)) { + mFilterProbe.bind(cursor); + ids.add(mFilterProbe.getConversationId()); + } + } + if (saved >= 0 && saved < cursor.getCount()) { + cursor.moveToPosition(saved); + } + return ids; + } + + /** Invokes {@code action} for each conversation row shown in the current filter. */ + public void forEachVisibleConversationId(final Consumer action) { + final Cursor cursor = getCursor(); + if (cursor == null || action == null) { + return; + } + for (final int position : mDisplayPositions) { + if (cursor.moveToPosition(position)) { + mFilterProbe.bind(cursor); + action.accept(mFilterProbe.getConversationId()); + } + } + } + + @Override + public Cursor swapCursor(final Cursor newCursor) { + final Cursor old = super.swapCursor(newCursor); + rebuildFilterIndex(); + return old; + } + + private void rebuildFilterIndex() { + final Cursor cursor = getCursor(); + if (cursor == null || cursor.getCount() == 0) { + mDisplayPositions = new int[0]; + return; + } + final ArrayList positions = new ArrayList<>(); + final int savedPosition = cursor.getPosition(); + for (int i = 0; i < cursor.getCount(); i++) { + if (!cursor.moveToPosition(i)) { + continue; + } + mFilterProbe.bind(cursor); + if (passesFilter()) { + positions.add(i); + } + } + if (savedPosition >= 0 && savedPosition < cursor.getCount()) { + cursor.moveToPosition(savedPosition); + } + sortPinnedFirst(positions, cursor); + mDisplayPositions = new int[positions.size()]; + for (int i = 0; i < positions.size(); i++) { + mDisplayPositions[i] = positions.get(i); + } + } + + private boolean passesFilter() { + if (mFilterMode == FILTER_ALL) { + return true; + } + if (mFilterMode == FILTER_UNREAD) { + return !mFilterProbe.getIsRead(); + } + if (mFilterMode == FILTER_GROUPS) { + return mFilterProbe.getParticipantCount() > 1; + } + return true; + } + + private void sortPinnedFirst(final ArrayList positions, final Cursor cursor) { + final List pinOrder = PinnedConversationStore.getPinnedIds(mContext); + if (pinOrder.isEmpty() || positions.isEmpty()) { + return; + } + final android.util.ArrayMap idToPosition = + new android.util.ArrayMap<>(positions.size()); + final int saved = cursor.getPosition(); + for (final int pos : positions) { + if (!cursor.moveToPosition(pos)) { + continue; + } + mFilterProbe.bind(cursor); + idToPosition.put(mFilterProbe.getConversationId(), pos); + } + if (saved >= 0 && saved < cursor.getCount()) { + cursor.moveToPosition(saved); + } + final LinkedHashSet ordered = new LinkedHashSet<>(positions.size()); + for (final String id : pinOrder) { + final Integer mapped = idToPosition.get(id); + if (mapped != null) { + ordered.add(mapped); + } + } + for (final int pos : positions) { + ordered.add(pos); + } + positions.clear(); + positions.addAll(ordered); + } + + private int mapPosition(final int displayIndex) { + return mDisplayPositions[displayIndex]; + } + + private int toDisplayIndex(final int adapterPosition) { + return adapterPosition - getPinnedHeaderOffset(); + } + + @Override + public int getItemViewType(final int position) { + if (hasPinnedHeader() && position == 0) { + return VIEW_TYPE_PINNED_HEADER; + } + return VIEW_TYPE_CONVERSATION; + } + + @Override + public int getItemCount() { + if (getCursor() == null) { + return hasPinnedHeader() ? 1 : 0; + } + return mDisplayPositions.length + getPinnedHeaderOffset(); + } + + @Override + public long getItemId(final int position) { + if (hasPinnedHeader() && position == 0) { + return PINNED_HEADER_ITEM_ID; + } + return super.getItemId(mapPosition(toDisplayIndex(position))); + } + + @NonNull + @Override + public RecyclerView.ViewHolder onCreateViewHolder(@NonNull final ViewGroup parent, + final int viewType) { + if (viewType == VIEW_TYPE_PINNED_HEADER) { + return createPinnedHeaderViewHolder(parent); + } + return createConversationViewHolder(parent); + } + + @Override + public void onBindViewHolder(@NonNull final RecyclerView.ViewHolder holder, + final int position) { + if (holder instanceof PinnedHeaderViewHolder) { + attachPinnedStripToHeader((PinnedHeaderViewHolder) holder); + return; + } + if (!(holder instanceof ConversationListViewHolder)) { + return; + } + if (!mDataValid) { + throw new IllegalStateException("this should only be called when the cursor is valid"); + } + final int cursorPosition = mapPosition(toDisplayIndex(position)); + if (!mCursor.moveToPosition(cursorPosition)) { + throw new IllegalStateException("couldn't move cursor to position " + cursorPosition); + } + bindViewHolder((ConversationListViewHolder) holder, mContext, mCursor); + } + + private PinnedHeaderViewHolder createPinnedHeaderViewHolder(final ViewGroup parent) { + final FrameLayout container = new FrameLayout(parent.getContext()); + container.setLayoutParams(new RecyclerView.LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.WRAP_CONTENT)); + container.setClipChildren(true); + container.setClipToPadding(true); + return new PinnedHeaderViewHolder(container); + } + + private void attachPinnedStripToHeader(final PinnedHeaderViewHolder holder) { + if (mPinnedStripRoot == null) { + return; + } + final ViewGroup container = (ViewGroup) holder.itemView; + if (mPinnedStripRoot.getParent() instanceof ViewGroup) { + ((ViewGroup) mPinnedStripRoot.getParent()).removeView(mPinnedStripRoot); + } + if (mPinnedStripRoot.getParent() != container) { + container.removeAllViews(); + container.addView(mPinnedStripRoot, new FrameLayout.LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.WRAP_CONTENT)); + } + holder.setIsRecyclable(false); + } + + private ConversationListViewHolder createConversationViewHolder(final ViewGroup parent) { + final LayoutInflater layoutInflater = LayoutInflater.from(mContext); + final ConversationListItemView itemView = + (ConversationListItemView) layoutInflater.inflate( + R.layout.conversation_list_item_view, parent, false); + return new ConversationListViewHolder(itemView); + } + + @Override + public RecyclerView.ViewHolder createViewHolder(final Context context, + final ViewGroup parent, final int viewType) { + return onCreateViewHolder(parent, viewType); + } + + @Override + public void bindViewHolder(final RecyclerView.ViewHolder holder, final Context context, + final Cursor cursor) { + if (holder instanceof ConversationListViewHolder) { + ((ConversationListViewHolder) holder).mView.bind(cursor, mClivHostInterface); + } + } + + /** + * ViewHolder that holds a ConversationListItemView. + */ + public static class ConversationListViewHolder extends RecyclerView.ViewHolder { + final ConversationListItemView mView; + + public ConversationListViewHolder(final ConversationListItemView itemView) { + super(itemView); + mView = itemView; + } + } + + static final class PinnedHeaderViewHolder extends RecyclerView.ViewHolder { + PinnedHeaderViewHolder(final View itemView) { + super(itemView); + } + } + + private static final class OffsetListUpdateCallback implements ListUpdateCallback { + private final RecyclerView.Adapter mAdapter; + private final int mOffset; + + OffsetListUpdateCallback(final RecyclerView.Adapter adapter, final int offset) { + mAdapter = adapter; + mOffset = offset; + } + + @Override + public void onInserted(final int position, final int count) { + mAdapter.notifyItemRangeInserted(position + mOffset, count); + } + + @Override + public void onRemoved(final int position, final int count) { + mAdapter.notifyItemRangeRemoved(position + mOffset, count); + } + + @Override + public void onMoved(final int fromPosition, final int toPosition) { + mAdapter.notifyItemMoved(fromPosition + mOffset, toPosition + mOffset); + } + + @Override + public void onChanged(final int position, final int count, final Object payload) { + mAdapter.notifyItemRangeChanged(position + mOffset, count, payload); + } + } +} diff --git a/app/src/main/java/com/android/messaging/ui/conversationlist/ConversationListFragment.java b/app/src/main/java/com/android/messaging/ui/conversationlist/ConversationListFragment.java new file mode 100644 index 0000000..1ee1c18 --- /dev/null +++ b/app/src/main/java/com/android/messaging/ui/conversationlist/ConversationListFragment.java @@ -0,0 +1,1239 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * Copyright (C) 2024-2025 The LineageOS Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.messaging.ui.conversationlist; + +import android.app.Activity; +import android.app.AlertDialog; +import android.content.Context; +import android.database.Cursor; +import android.graphics.Rect; +import android.net.Uri; +import android.os.Bundle; +import android.os.Parcelable; +import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.view.View; +import android.view.ViewGroup; +import android.view.ViewGroup.MarginLayoutParams; +import android.view.ViewPropertyAnimator; +import android.view.accessibility.AccessibilityManager; +import android.widget.AbsListView; +import android.widget.ImageButton; +import android.widget.ImageView; +import android.widget.PopupWindow; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.annotation.NonNull; +import androidx.core.content.ContextCompat; +import androidx.core.view.ViewGroupCompat; +import androidx.fragment.app.Fragment; +import androidx.loader.app.LoaderManager; +import androidx.recyclerview.widget.DefaultItemAnimator; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.android.messaging.R; +import com.android.messaging.datamodel.DataModel; +import com.android.messaging.datamodel.action.MarkAsReadAction; +import com.android.messaging.datamodel.binding.Binding; +import com.android.messaging.datamodel.binding.BindingBase; +import com.android.messaging.datamodel.data.ConversationListData; +import com.android.messaging.datamodel.data.ConversationListData.ConversationListDataListener; +import com.android.messaging.datamodel.data.ConversationListItemData; +import com.android.messaging.ui.ListEmptyView; +import com.android.messaging.ui.SnackBarInteraction; +import com.android.messaging.ui.UIIntents; +import com.android.messaging.ui.home.HomeContactsFragment; +import com.android.messaging.ui.home.HomePinnedStrip; +import com.android.messaging.ui.home.PinnedConversationStore; +import com.android.messaging.util.AccessibilityUtil; +import com.android.messaging.util.ImeUtil; +import com.android.messaging.util.LogUtil; +import com.android.messaging.util.UiUtils; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +/** + * Shows a list of conversations. + */ +public class ConversationListFragment extends Fragment implements ConversationListDataListener, + ConversationListItemView.HostInterface { + private static final String BUNDLE_ARCHIVED_MODE = "archived_mode"; + private static final String BUNDLE_FORWARD_MESSAGE_MODE = "forward_message_mode"; + + private MenuItem mShowBlockedMenuItem; + private boolean mArchiveMode; + private boolean mBlockedAvailable; + private boolean mForwardMessageMode; + + public interface ConversationListFragmentHost { + void onConversationClick(final ConversationListData listData, + final ConversationListItemData conversationListItemData, + final boolean isLongClick, + final ConversationListItemView conversationView); + void onCreateConversationClick(); + boolean isConversationSelected(final String conversationId); + boolean isSwipeAnimatable(); + boolean isSelectionMode(); + boolean hasWindowFocus(); + } + + private ConversationListFragmentHost mHost; + private View mRootView; + private View mHomeHeader; + private View mHomeSelectionHeader; + private View mHomeBottomNav; + private View mHomeSelectionBar; + private ImageButton mHomeSelectionDelete; + private View mHomeMessagesTop; + private View mHomePinnedStrip; + private TextView mHomeEditButton; + private ImageButton mHomePinnedDoneButton; + private boolean mHomePinnedEditMode; + private ViewGroup mHomeContactsHost; + private View mHomeNavMessages; + private View mHomeNavContacts; + private ImageView mHomeNavMessagesIcon; + private ImageView mHomeNavContactsIcon; + private TextView mHomeNavMessagesLabel; + private TextView mHomeNavContactsLabel; + private int mHomeTab = HOME_TAB_MESSAGES; + private RecyclerView mRecyclerView; + private View mHomeComposeContainer; + private ImageButton mStartNewConversationButton; + private ListEmptyView mEmptyListMessageView; + private ConversationListAdapter mAdapter; + + // Saved Instance State Data - only for temporal data which is nice to maintain but not + // critical for correctness. + private static final String SAVED_INSTANCE_STATE_LIST_VIEW_STATE_KEY = + "conversationListViewState"; + private static final String SAVED_INSTANCE_STATE_SEARCH_BAR_EXPANDED = + "homeSearchBarExpanded"; + private static final String SAVED_INSTANCE_STATE_HOME_TAB = "homeTab"; + private static final String SAVED_INSTANCE_STATE_PINNED_EDIT = "homePinnedEdit"; + private static final String HOME_CONTACTS_FRAGMENT_TAG = "home_contacts"; + private static final int HOME_TAB_MESSAGES = 0; + private static final int HOME_TAB_CONTACTS = 1; + private static final int SEARCH_NEWEST_EDGE_SLOP_DP = 48; + private static final int SEARCH_BAR_ANIM_MS = 280; + private static final int SEARCH_BAR_SLIDE_FALLBACK_DP = 72; + + private Parcelable mListState; + private View mSearchBar; + private boolean mSearchBarShown; + + final Binding mListBinding = BindingBase.createBinding(this); + private final ConversationListItemData mPinnedRowProbe = new ConversationListItemData(); + private final HomePinnedStrip.Listener mPinnedStripListener = new HomePinnedStrip.Listener() { + @Override + public void onPinnedConversationClicked(final String conversationId) { + openConversationById(conversationId); + } + + @Override + public void onPinnedConversationUnpin(final String conversationId) { + PinnedConversationStore.unpin(requireContext(), conversationId); + mAdapter.refreshPinOrdering(); + refreshPinnedStrip(); + } + }; + + public static ConversationListFragment createArchivedConversationListFragment() { + return createConversationListFragment(BUNDLE_ARCHIVED_MODE); + } + + public static ConversationListFragment createForwardMessageConversationListFragment() { + return createConversationListFragment(BUNDLE_FORWARD_MESSAGE_MODE); + } + + public static ConversationListFragment createConversationListFragment(String modeKeyName) { + final ConversationListFragment fragment = new ConversationListFragment(); + if (modeKeyName != null) { + final Bundle bundle = new Bundle(); + bundle.putBoolean(modeKeyName, true); + fragment.setArguments(bundle); + } + return fragment; + } + + /** + * {@inheritDoc} from Fragment + */ + @Override + public void onCreate(final Bundle bundle) { + super.onCreate(bundle); + mListBinding.getData().init(LoaderManager.getInstance(this), mListBinding); + mAdapter = new ConversationListAdapter(getActivity(), null, this); + } + + @Override + public void onResume() { + super.onResume(); + + mHost = (ConversationListFragmentHost) getActivity(); + setScrolledToNewestConversationIfNeeded(); + applySearchBarVisibility(); + resetSearchBarScrollTracking(); + updateHomeMainNavVisibility(); + refreshPinnedStrip(); + updateUi(); + } + + public void setScrolledToNewestConversationIfNeeded() { + if (!mArchiveMode + && !mForwardMessageMode + && isScrolledToFirstConversation() + && mHost.hasWindowFocus()) { + mListBinding.getData().setScrolledToNewestConversation(true); + } + } + + private boolean isScrolledToFirstConversation() { + int firstItemPosition = ((LinearLayoutManager) mRecyclerView.getLayoutManager()) + .findFirstCompletelyVisibleItemPosition(); + if (firstItemPosition == RecyclerView.NO_POSITION) { + return false; + } + return firstItemPosition <= mAdapter.getFirstConversationAdapterPosition(); + } + + /** + * {@inheritDoc} from Fragment + */ + @Override + public void onDestroy() { + super.onDestroy(); + mListBinding.unbind(); + mHost = null; + } + + /** + * {@inheritDoc} from Fragment + */ + @Override + public View onCreateView(final LayoutInflater inflater, final ViewGroup container, + final Bundle savedInstanceState) { + final ViewGroup rootView = (ViewGroup) inflater.inflate(R.layout.conversation_list_fragment, + container, false); + mRecyclerView = rootView.findViewById(android.R.id.list); + mEmptyListMessageView = rootView.findViewById(R.id.no_conversations_view); + mEmptyListMessageView.setImageHint(R.drawable.ic_oobe_conv_list); + // The default behavior for default layout param generation by LinearLayoutManager is to + // provide width and height of WRAP_CONTENT, but this is not desirable for + // ConversationListFragment; the view in each row should be a width of MATCH_PARENT so that + // the entire row is tappable. + final Activity activity = getActivity(); + final LinearLayoutManager manager = new LinearLayoutManager(activity) { + @Override + public RecyclerView.LayoutParams generateDefaultLayoutParams() { + return new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.WRAP_CONTENT); + } + }; + mRecyclerView.setLayoutManager(manager); + mRecyclerView.setHasFixedSize(false); + final DefaultItemAnimator itemAnimator = new DefaultItemAnimator(); + itemAnimator.setMoveDuration(220); + itemAnimator.setChangeDuration(180); + mRecyclerView.setItemAnimator(itemAnimator); + mHomePinnedStrip = inflater.inflate(R.layout.home_pinned_strip, rootView, false); + mAdapter.setPinnedStripRoot(mHomePinnedStrip); + mRecyclerView.setAdapter(mAdapter); + mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { + int mCurrentState = AbsListView.OnScrollListener.SCROLL_STATE_IDLE; + + @Override + public void onScrolled(@NonNull final RecyclerView recyclerView, final int dx, + final int dy) { + if (mCurrentState == AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL + || mCurrentState == AbsListView.OnScrollListener.SCROLL_STATE_FLING) { + ImeUtil.get().hideImeKeyboard(getActivity(), mRecyclerView); + } + + if (isScrolledToFirstConversation()) { + setScrolledToNewestConversationIfNeeded(); + } else { + mListBinding.getData().setScrolledToNewestConversation(false); + } + + if (!mArchiveMode && !mForwardMessageMode) { + handleSearchBarByScrollOffset(dy); + } + } + + @Override + public void onScrollStateChanged(@NonNull final RecyclerView recyclerView, + final int newState) { + mCurrentState = newState; + } + }); + mRecyclerView.addOnItemTouchListener(new ConversationListSwipeHelper(mRecyclerView)); + + if (savedInstanceState != null) { + mListState = savedInstanceState.getParcelable(SAVED_INSTANCE_STATE_LIST_VIEW_STATE_KEY, + Parcelable.class); + mSearchBarShown = savedInstanceState.getBoolean( + SAVED_INSTANCE_STATE_SEARCH_BAR_EXPANDED, false); + } + + mRootView = rootView; + mHomeHeader = rootView.findViewById(R.id.home_header); + mHomeSelectionHeader = rootView.findViewById(R.id.home_selection_header); + mHomeBottomNav = rootView.findViewById(R.id.home_bottom_nav); + mHomeSelectionBar = rootView.findViewById(R.id.home_selection_bar); + mHomeSelectionDelete = rootView.findViewById(R.id.home_selection_delete); + + mHomeComposeContainer = rootView.findViewById(R.id.home_compose_container); + mStartNewConversationButton = rootView.findViewById(R.id.home_nav_search); + if (mArchiveMode || mForwardMessageMode) { + if (mHomeComposeContainer != null) { + mHomeComposeContainer.setVisibility(View.GONE); + } + hideHomeChrome(rootView); + } else { + if (mStartNewConversationButton != null) { + mStartNewConversationButton.setOnClickListener(v -> { + if (mHost != null) { + mHost.onCreateConversationClick(); + } + }); + } + setupHomeChrome(rootView); + mHomeMessagesTop = rootView.findViewById(R.id.home_messages_top); + mHomeContactsHost = rootView.findViewById(R.id.home_contacts_host); + mHomeNavMessages = rootView.findViewById(R.id.home_nav_messages); + mHomeNavContacts = rootView.findViewById(R.id.home_nav_contacts); + bindHomeNavTab(mHomeNavMessages, R.drawable.ic_home_nav_messages, + R.string.home_nav_messages); + bindHomeNavTab(mHomeNavContacts, R.drawable.ic_home_nav_contacts, + R.string.home_nav_contacts); + bindHomeNavTab(rootView.findViewById(R.id.home_nav_automate), + R.drawable.ic_home_nav_automate, R.string.home_nav_automate); + mHomeNavMessagesIcon = mHomeNavMessages.findViewById(R.id.home_nav_tab_icon); + mHomeNavContactsIcon = mHomeNavContacts.findViewById(R.id.home_nav_tab_icon); + mHomeNavMessagesLabel = mHomeNavMessages.findViewById(R.id.home_nav_tab_label); + mHomeNavContactsLabel = mHomeNavContacts.findViewById(R.id.home_nav_tab_label); + if (savedInstanceState != null) { + mHomeTab = savedInstanceState.getInt(SAVED_INSTANCE_STATE_HOME_TAB, + HOME_TAB_MESSAGES); + mHomePinnedEditMode = savedInstanceState.getBoolean( + SAVED_INSTANCE_STATE_PINNED_EDIT, false); + } + selectHomeTab(mHomeTab); + updateHomeEditButtonForPinnedMode(); + } + + // The root view has a non-null background, which by default is deemed by the framework + // to be a "transition group," where all child views are animated together during an + // activity transition. However, we want each individual items in the recycler view to + // show explode animation themselves, so we explicitly tag the root view to be a non-group. + ViewGroupCompat.setTransitionGroup(rootView, false); + + setHasOptionsMenu(true); + return rootView; + } + + private void bindHomeNavTab(final View tabRoot, final int iconRes, final int labelRes) { + if (tabRoot == null) { + return; + } + final ImageView icon = tabRoot.findViewById(R.id.home_nav_tab_icon); + final TextView label = tabRoot.findViewById(R.id.home_nav_tab_label); + if (icon != null) { + icon.setImageResource(iconRes); + } + if (label != null) { + label.setText(labelRes); + } + } + + private void hideHomeChrome(final View rootView) { + setGone(rootView, R.id.home_messages_top); + setGone(rootView, R.id.home_contacts_host); + setGone(rootView, R.id.home_search_bar_container); + setGone(rootView, R.id.home_bottom_nav); + setGone(rootView, R.id.home_selection_bar); + } + + private static void setGone(final View root, final int id) { + final View view = root.findViewById(id); + if (view != null) { + view.setVisibility(View.GONE); + } + } + + private int dpToPx(final int dp) { + final float density = getResources().getDisplayMetrics().density; + return (int) (dp * density + 0.5f); + } + + private void setupSearchBarScroll(final View searchBar) { + searchBar.addOnLayoutChangeListener( + (v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) -> { + if (bottom - top != oldBottom - oldTop && mSearchBarShown) { + updateListPaddingForSearchBar(); + } + }); + searchBar.post(() -> { + applySearchBarVisibility(); + resetSearchBarScrollTracking(); + }); + } + + private void resetSearchBarScrollTracking() { + // No scroll state is kept; visibility is derived from the live scroll position. + } + + /** Toward older rows → keep search visible. Toward recent rows → hide. */ + private void handleSearchBarByScrollOffset(final int dy) { + if (mHomeTab != HOME_TAB_MESSAGES || isSelectionMode() || mHomePinnedEditMode + || mSearchBar == null || mRecyclerView == null || dy == 0) { + return; + } + if (dy > 0) { + showSearchBar(); + } else { + hideSearchBar(); + } + } + + private void cancelSearchBarAnimation() { + if (mSearchBar != null) { + mSearchBar.animate().cancel(); + } + } + + private float getSearchBarSlideDistancePx() { + if (mSearchBar == null) { + return dpToPx(SEARCH_BAR_SLIDE_FALLBACK_DP); + } + final int height = mSearchBar.getHeight(); + return height > 0 ? height : dpToPx(SEARCH_BAR_SLIDE_FALLBACK_DP); + } + + private void updateListPaddingForSearchBar() { + if (mRecyclerView == null) { + return; + } + int top = 0; + if (mSearchBarShown && mSearchBar != null + && mSearchBar.getVisibility() != View.GONE) { + top = mSearchBar.getHeight(); + if (top == 0) { + top = dpToPx(SEARCH_BAR_SLIDE_FALLBACK_DP); + } + } + mRecyclerView.setPadding( + mRecyclerView.getPaddingLeft(), + top, + mRecyclerView.getPaddingRight(), + mRecyclerView.getPaddingBottom()); + } + + private void applySearchBarVisibility() { + if (mSearchBar == null || mHomeTab != HOME_TAB_MESSAGES) { + return; + } + if (mHomePinnedEditMode) { + cancelSearchBarAnimation(); + mSearchBar.setVisibility(View.GONE); + mSearchBar.setAlpha(1f); + mSearchBar.setTranslationY(0f); + updateListPaddingForSearchBar(); + return; + } + cancelSearchBarAnimation(); + if (mSearchBarShown) { + mSearchBar.setVisibility(View.VISIBLE); + mSearchBar.setAlpha(1f); + mSearchBar.setTranslationY(0f); + updateListPaddingForSearchBar(); + mSearchBar.post(this::updateListPaddingForSearchBar); + } else { + mSearchBar.setVisibility(View.GONE); + mSearchBar.setAlpha(1f); + mSearchBar.setTranslationY(0f); + updateListPaddingForSearchBar(); + } + } + + private void runSearchBarShowAnimation() { + updateListPaddingForSearchBar(); + final float slide = getSearchBarSlideDistancePx(); + mSearchBar.setTranslationY(-slide); + mSearchBar.setAlpha(0f); + mSearchBar.animate() + .translationY(0f) + .alpha(1f) + .setDuration(SEARCH_BAR_ANIM_MS) + .setInterpolator(UiUtils.DEFAULT_INTERPOLATOR) + .withEndAction(this::updateListPaddingForSearchBar); + } + + private void showSearchBar() { + if (mHomeTab != HOME_TAB_MESSAGES || isSelectionMode() || mHomePinnedEditMode + || mSearchBar == null || mSearchBarShown) { + return; + } + mSearchBarShown = true; + cancelSearchBarAnimation(); + mSearchBar.setVisibility(View.VISIBLE); + updateListPaddingForSearchBar(); + if (mSearchBar.getHeight() == 0) { + mSearchBar.post(() -> { + updateListPaddingForSearchBar(); + runSearchBarShowAnimation(); + }); + } else { + runSearchBarShowAnimation(); + } + } + + private void hideSearchBar() { + if (mSearchBar == null || !mSearchBarShown) { + return; + } + mSearchBarShown = false; + cancelSearchBarAnimation(); + final float slide = getSearchBarSlideDistancePx(); + mSearchBar.animate() + .translationY(-slide) + .alpha(0f) + .setDuration(SEARCH_BAR_ANIM_MS) + .setInterpolator(UiUtils.DEFAULT_INTERPOLATOR) + .withEndAction(() -> { + if (!mSearchBarShown && mSearchBar != null) { + mSearchBar.setVisibility(View.GONE); + mSearchBar.setTranslationY(0f); + mSearchBar.setAlpha(1f); + updateListPaddingForSearchBar(); + } + }); + } + + private void setupHomeChrome(final View rootView) { + final View editButton = rootView.findViewById(R.id.home_edit_button); + final View filterButton = rootView.findViewById(R.id.home_filter_button); + final View searchBarContainer = rootView.findViewById(R.id.home_search_bar_container); + final View searchBar = rootView.findViewById(R.id.home_search_bar); + final View navMessages = rootView.findViewById(R.id.home_nav_messages); + final View navContacts = rootView.findViewById(R.id.home_nav_contacts); + final View navAutomate = rootView.findViewById(R.id.home_nav_automate); + + if (editButton instanceof TextView) { + mHomeEditButton = (TextView) editButton; + } + mHomePinnedDoneButton = rootView.findViewById(R.id.home_pinned_done); + updateHomeEditButtonForPinnedMode(); + if (filterButton != null) { + filterButton.setOnClickListener(this::showHomeFilterPopover); + } + final View.OnClickListener openCompose = v -> + UIIntents.get().launchCreateNewConversationActivity(requireActivity(), null); + mSearchBar = searchBarContainer != null ? searchBarContainer : searchBar; + if (searchBar != null) { + searchBar.setOnClickListener(openCompose); + } + if (mSearchBar != null) { + setupSearchBarScroll(mSearchBar); + } + updateSearchBarForPinnedEditMode(); + if (navMessages != null) { + navMessages.setOnClickListener(v -> selectHomeTab(HOME_TAB_MESSAGES)); + } + if (navContacts != null) { + navContacts.setOnClickListener(v -> selectHomeTab(HOME_TAB_CONTACTS)); + } + if (navAutomate != null) { + navAutomate.setOnClickListener(v -> + Toast.makeText(requireContext(), R.string.home_automate_coming_soon, + Toast.LENGTH_SHORT).show()); + } + + final View selectionDone = rootView.findViewById(R.id.home_selection_done); + if (selectionDone != null) { + selectionDone.setOnClickListener(v -> { + if (getActivity() instanceof AbstractConversationListActivity) { + ((AbstractConversationListActivity) getActivity()).exitMultiSelectState(); + } + }); + } + final View readAll = rootView.findViewById(R.id.home_read_all_button); + if (readAll != null) { + readAll.setOnClickListener(v -> markAllVisibleConversationsRead()); + } + if (mHomeSelectionDelete != null) { + mHomeSelectionDelete.setOnClickListener(v -> { + if (getActivity() instanceof AbstractConversationListActivity) { + ((AbstractConversationListActivity) getActivity()) + .deleteSelectedConversations(); + } + }); + } + } + + public void setHomeSelectionMode(final boolean enabled) { + if (mArchiveMode || mForwardMessageMode || mRootView == null) { + return; + } + if (mHomeHeader != null) { + mHomeHeader.setVisibility(enabled ? View.GONE : View.VISIBLE); + } + if (mHomeSelectionHeader != null) { + mHomeSelectionHeader.setVisibility(enabled ? View.VISIBLE : View.GONE); + } + if (enabled && mHomeBottomNav != null) { + mHomeBottomNav.setVisibility(View.GONE); + } + if (mHomeSelectionBar != null) { + mHomeSelectionBar.setVisibility(enabled ? View.VISIBLE : View.GONE); + } + if (enabled) { + setPinnedEditMode(false); + updateHomeComposeButtonVisibility(); + refreshPinnedStrip(); + if (mHomeMessagesTop != null) { + mHomeMessagesTop.bringToFront(); + } + } else { + updateHomeMainNavVisibility(); + refreshPinnedStrip(); + } + if (enabled) { + mSearchBarShown = false; + cancelSearchBarAnimation(); + if (mSearchBar != null) { + mSearchBar.setVisibility(View.GONE); + mSearchBar.setAlpha(1f); + mSearchBar.setTranslationY(0f); + } + updateListPaddingForSearchBar(); + } + updateHomeSelectionDeleteEnabled(0); + updateUi(); + } + + private void selectHomeTab(final int tab) { + if (mArchiveMode || mForwardMessageMode || mRootView == null) { + return; + } + if (isSelectionMode() && tab != HOME_TAB_MESSAGES) { + return; + } + mHomeTab = tab; + final boolean showMessages = tab == HOME_TAB_MESSAGES; + if (mHomeMessagesTop != null) { + mHomeMessagesTop.setVisibility(showMessages ? View.VISIBLE : View.GONE); + } + if (mHomeContactsHost != null) { + mHomeContactsHost.setVisibility(showMessages ? View.GONE : View.VISIBLE); + if (!showMessages) { + ensureHomeContactsFragment(); + } + } + if (!showMessages) { + mSearchBarShown = false; + cancelSearchBarAnimation(); + if (mSearchBar != null) { + mSearchBar.setVisibility(View.GONE); + mSearchBar.setAlpha(1f); + mSearchBar.setTranslationY(0f); + } + updateListPaddingForSearchBar(); + if (mEmptyListMessageView != null) { + mEmptyListMessageView.setVisibility(View.GONE); + } + } else { + applySearchBarVisibility(); + updateEmptyListUi(mAdapter.getConversationItemCount() == 0); + } + updateHomeComposeButtonVisibility(); + updateHomeNavHighlight(); + updateHomeMainNavVisibility(); + refreshPinnedStrip(); + } + + /** Main tabs show nav; selection mode and other activities hide it ({@link #onPause}). */ + private void updateHomeMainNavVisibility() { + if (mHomeBottomNav == null || mArchiveMode || mForwardMessageMode) { + return; + } + if (isSelectionMode()) { + mHomeBottomNav.setVisibility(View.GONE); + } else { + mHomeBottomNav.setVisibility(isResumed() ? View.VISIBLE : View.GONE); + } + updateHomeComposeButtonVisibility(); + } + + private void updateHomeComposeButtonVisibility() { + if (mArchiveMode || mForwardMessageMode) { + return; + } + final boolean showCompose = isResumed() && mHomeTab == HOME_TAB_MESSAGES + && !isSelectionMode(); + if (mHomeComposeContainer != null) { + mHomeComposeContainer.setVisibility(showCompose ? View.VISIBLE : View.GONE); + } + if (mStartNewConversationButton != null && showCompose) { + mStartNewConversationButton.animate().cancel(); + mStartNewConversationButton.setTranslationX(0f); + mStartNewConversationButton.setVisibility(View.VISIBLE); + mStartNewConversationButton.setEnabled(true); + } + } + + private void launchHomeSubScreen(final Runnable action) { + if (mHomeBottomNav != null) { + mHomeBottomNav.setVisibility(View.GONE); + } + if (mHomeComposeContainer != null) { + mHomeComposeContainer.setVisibility(View.GONE); + } + action.run(); + } + + private void ensureHomeContactsFragment() { + if (mHomeContactsHost == null + || getChildFragmentManager().findFragmentById(R.id.home_contacts_host) != null) { + return; + } + getChildFragmentManager().beginTransaction() + .replace(R.id.home_contacts_host, new HomeContactsFragment(), + HOME_CONTACTS_FRAGMENT_TAG) + .commit(); + } + + private void updateHomeNavHighlight() { + final boolean messagesActive = mHomeTab == HOME_TAB_MESSAGES; + applyHomeNavTabStyle(mHomeNavMessages, mHomeNavMessagesIcon, mHomeNavMessagesLabel, + messagesActive); + applyHomeNavTabStyle(mHomeNavContacts, mHomeNavContactsIcon, mHomeNavContactsLabel, + !messagesActive); + } + + private void applyHomeNavTabStyle(final View tab, final ImageView icon, final TextView label, + final boolean active) { + if (tab == null) { + return; + } + if (active) { + tab.setBackgroundResource(R.drawable.home_bg_nav_active_primary); + } else { + tab.setBackgroundResource(android.R.color.transparent); + } + final int color = ContextCompat.getColor(requireContext(), + active ? R.color.home_nav_active_content : R.color.home_nav_inactive); + if (icon != null) { + icon.setImageTintList(android.content.res.ColorStateList.valueOf(color)); + } + if (label != null) { + label.setTextColor(color); + label.setTypeface(null, active ? android.graphics.Typeface.BOLD + : android.graphics.Typeface.NORMAL); + } + } + + public void updateHomeSelectionDeleteEnabled(final int selectedCount) { + if (mHomeSelectionDelete == null) { + return; + } + final boolean enabled = selectedCount > 0; + mHomeSelectionDelete.setEnabled(enabled); + mHomeSelectionDelete.setAlpha(1f); + mHomeSelectionDelete.setImageAlpha(enabled ? 255 : 102); + } + + private void markAllVisibleConversationsRead() { + mAdapter.forEachVisibleConversationId(MarkAsReadAction::markAsRead); + } + + private PopupWindow mHomePopover; + + private void dismissHomePopover() { + if (mHomePopover != null && mHomePopover.isShowing()) { + mHomePopover.dismiss(); + } + mHomePopover = null; + } + + private PopupWindow showHomePopover(final View anchor, final int layoutResId, + final boolean alignEnd) { + dismissHomePopover(); + final View content = LayoutInflater.from(requireContext()) + .inflate(layoutResId, null, false); + content.measure( + View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED), + View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)); + final PopupWindow popup = new PopupWindow(content, + content.getMeasuredWidth(), + ViewGroup.LayoutParams.WRAP_CONTENT, + true); + popup.setOutsideTouchable(true); + popup.setFocusable(true); + popup.setElevation(16f); + popup.setBackgroundDrawable(new android.graphics.drawable.ColorDrawable( + android.graphics.Color.TRANSPARENT)); + popup.setOnDismissListener(() -> { + if (mHomePopover == popup) { + mHomePopover = null; + } + }); + final int xOff = alignEnd + ? Math.max(0, anchor.getWidth() - content.getMeasuredWidth()) + : 0; + popup.showAsDropDown(anchor, xOff, 8); + mHomePopover = popup; + return popup; + } + + private void showHomeFilterPopover(final View anchor) { + final PopupWindow popup = showHomePopover(anchor, R.layout.home_popover_filter, true); + final View content = popup.getContentView(); + content.findViewById(R.id.popover_messages).setOnClickListener(v -> { + selectHomeChip(ConversationListAdapter.FILTER_ALL); + dismissHomePopover(); + }); + content.findViewById(R.id.popover_spam).setOnClickListener(v -> { + dismissHomePopover(); + launchHomeSubScreen(() -> UIIntents.get().launchBlockedParticipantsActivity( + requireActivity())); + }); + content.findViewById(R.id.popover_recently_deleted).setOnClickListener(v -> { + dismissHomePopover(); + launchHomeSubScreen(() -> UIIntents.get().launchArchivedConversationsActivity( + requireActivity())); + }); + content.findViewById(R.id.popover_unread).setOnClickListener(v -> { + selectHomeChip(ConversationListAdapter.FILTER_UNREAD); + dismissHomePopover(); + }); + content.findViewById(R.id.popover_work).setOnClickListener(v -> { + dismissHomePopover(); + Toast.makeText(requireContext(), R.string.home_popover_coming_soon, + Toast.LENGTH_SHORT).show(); + }); + content.findViewById(R.id.popover_personal).setOnClickListener(v -> { + selectHomeChip(ConversationListAdapter.FILTER_ALL); + dismissHomePopover(); + }); + content.findViewById(R.id.popover_settings).setOnClickListener(v -> { + dismissHomePopover(); + launchHomeSubScreen(() -> { + if (getActivity() instanceof ConversationListActivity) { + ((ConversationListActivity) getActivity()).onActionBarSettings(); + } + }); + }); + } + + private void showHomeEditPopover(final View anchor) { + final PopupWindow popup = showHomePopover(anchor, R.layout.home_popover_edit, false); + final View content = popup.getContentView(); + content.findViewById(R.id.popover_select_messages).setOnClickListener(v -> { + dismissHomePopover(); + if (getActivity() instanceof ConversationListActivity) { + ((ConversationListActivity) getActivity()).enterHomeEditMode(); + } + }); + content.findViewById(R.id.popover_edit_pinned).setOnClickListener(v -> { + dismissHomePopover(); + setPinnedEditMode(true); + }); + content.findViewById(R.id.popover_name_photo).setOnClickListener(v -> { + dismissHomePopover(); + launchHomeSubScreen(() -> { + if (getActivity() instanceof ConversationListActivity) { + ((ConversationListActivity) getActivity()).onActionBarSettings(); + } + }); + }); + } + + private void selectHomeChip(final int filterMode) { + mAdapter.setFilterMode(filterMode); + updateEmptyListUi(mAdapter.getConversationItemCount() == 0); + } + + @Override + public void onAttach(@NonNull final Context context) { + super.onAttach(context); + LogUtil.v(LogUtil.BUGLE_TAG, "Attaching List"); + final Bundle arguments = getArguments(); + if (arguments != null) { + mArchiveMode = arguments.getBoolean(BUNDLE_ARCHIVED_MODE, false); + mForwardMessageMode = arguments.getBoolean(BUNDLE_FORWARD_MESSAGE_MODE, false); + } + mListBinding.bind(DataModel.get().createConversationListData(context, this, mArchiveMode)); + } + + + @Override + public void onSaveInstanceState(@NonNull final Bundle outState) { + super.onSaveInstanceState(outState); + if (mListState != null) { + outState.putParcelable(SAVED_INSTANCE_STATE_LIST_VIEW_STATE_KEY, mListState); + } + outState.putBoolean(SAVED_INSTANCE_STATE_SEARCH_BAR_EXPANDED, mSearchBarShown); + outState.putInt(SAVED_INSTANCE_STATE_HOME_TAB, mHomeTab); + outState.putBoolean(SAVED_INSTANCE_STATE_PINNED_EDIT, mHomePinnedEditMode); + } + + @Override + public void onPause() { + super.onPause(); + dismissHomePopover(); + if (mHomeBottomNav != null && !mArchiveMode && !mForwardMessageMode) { + mHomeBottomNav.setVisibility(View.GONE); + } + mListState = mRecyclerView.getLayoutManager().onSaveInstanceState(); + mListBinding.getData().setScrolledToNewestConversation(false); + } + + @Override + public void onConversationListCursorUpdated(final ConversationListData data, + final Cursor cursor) { + mListBinding.ensureBound(data); + final Cursor oldCursor = mAdapter.swapCursor(cursor); + prunePinnedConversations(cursor); + refreshPinnedStrip(); + updateEmptyListUi(mAdapter.getConversationItemCount() == 0); + if (mListState != null && cursor != null && oldCursor == null) { + mRecyclerView.getLayoutManager().onRestoreInstanceState(mListState); + } + } + + @Override + public void setBlockedParticipantsAvailable(final boolean blockedAvailable) { + mBlockedAvailable = blockedAvailable; + if (mShowBlockedMenuItem != null) { + mShowBlockedMenuItem.setVisible(blockedAvailable); + } + } + + public void updateUi() { + mAdapter.notifyDataSetChanged(); + } + + @Override + public void onPrepareOptionsMenu(@NonNull final Menu menu) { + super.onPrepareOptionsMenu(menu); + final MenuItem startNewConversationMenuItem = + menu.findItem(R.id.action_start_new_conversation); + if (startNewConversationMenuItem != null) { + // It is recommended for the Floating Action button functionality to be duplicated as a + // menu + AccessibilityManager accessibilityManager = (AccessibilityManager) + requireActivity().getSystemService(Context.ACCESSIBILITY_SERVICE); + startNewConversationMenuItem.setVisible(accessibilityManager + .isTouchExplorationEnabled()); + } + + final MenuItem archive = menu.findItem(R.id.action_show_archived); + if (archive != null) { + archive.setVisible(true); + } + } + + @Override + public void onCreateOptionsMenu(@NonNull final Menu menu, + @NonNull final MenuInflater inflater) { + if (!isAdded()) { + // Guard against being called before we're added to the activity + return; + } + + mShowBlockedMenuItem = menu.findItem(R.id.action_show_blocked_contacts); + if (mShowBlockedMenuItem != null) { + mShowBlockedMenuItem.setVisible(mBlockedAvailable); + } + } + + /** + * {@inheritDoc} from ConversationListItemView.HostInterface + */ + @Override + public void onConversationClicked(final ConversationListItemData conversationListItemData, + final boolean isLongClick, final ConversationListItemView conversationView) { + final ConversationListData listData = mListBinding.getData(); + mHost.onConversationClick(listData, conversationListItemData, isLongClick, + conversationView); + } + + /** + * {@inheritDoc} from ConversationListItemView.HostInterface + */ + @Override + public boolean isConversationSelected(final String conversationId) { + return mHost.isConversationSelected(conversationId); + } + + @Override + public boolean shouldShowConversationPinButton() { + return mHomePinnedEditMode && !mArchiveMode && !mForwardMessageMode + && mHomeTab == HOME_TAB_MESSAGES; + } + + @Override + public boolean isConversationPinned(final String conversationId) { + return PinnedConversationStore.isPinned(requireContext(), conversationId); + } + + @Override + public void onConversationPinButtonClicked(final String conversationId) { + final boolean wasPinned = PinnedConversationStore.isPinned(requireContext(), + conversationId); + if (wasPinned) { + PinnedConversationStore.unpin(requireContext(), conversationId); + } else if (!PinnedConversationStore.pin(requireContext(), conversationId)) { + showPinnedLimitDialog(); + return; + } + mAdapter.refreshPinOrderingAnimated(); + final int adapterPosition = mAdapter.getAdapterPositionForConversationId(conversationId); + if (adapterPosition >= 0) { + mAdapter.notifyItemChanged(adapterPosition); + } + refreshPinnedStrip(); + if (!wasPinned && mRecyclerView != null) { + mRecyclerView.smoothScrollToPosition(mAdapter.getFirstConversationAdapterPosition()); + } + } + + @Override + public boolean isSwipeAnimatable() { + return mHost.isSwipeAnimatable(); + } + + // Show and hide empty list UI as needed with appropriate text based on view specifics + private void updateEmptyListUi(final boolean isEmpty) { + if (isEmpty) { + int emptyListText; + if (!mListBinding.getData().getHasFirstSyncCompleted()) { + emptyListText = R.string.conversation_list_first_sync_text; + } else if (mArchiveMode) { + emptyListText = R.string.archived_conversation_list_empty_text; + } else { + emptyListText = R.string.conversation_list_empty_text; + } + mEmptyListMessageView.setTextHint(emptyListText); + mEmptyListMessageView.setVisibility(View.VISIBLE); + mEmptyListMessageView.setIsImageVisible(true); + mEmptyListMessageView.setIsVerticallyCentered(true); + } else { + mEmptyListMessageView.setVisibility(View.GONE); + } + } + + @Override + public List getSnackBarInteractions() { + final List interactions = new ArrayList<>(1); + final SnackBarInteraction fabInteraction = + new SnackBarInteraction.BasicSnackBarInteraction(mStartNewConversationButton); + interactions.add(fabInteraction); + return interactions; + } + + private ViewPropertyAnimator getNormalizedFabAnimator() { + return mStartNewConversationButton.animate() + .setInterpolator(UiUtils.DEFAULT_INTERPOLATOR) + .setDuration(getActivity().getResources().getInteger( + R.integer.fab_animation_duration_ms)); + } + + public void dismissFab() { + // To prevent clicking while animating. + mStartNewConversationButton.setEnabled(false); + final MarginLayoutParams lp = + (MarginLayoutParams) mStartNewConversationButton.getLayoutParams(); + final float fabWidthWithLeftRightMargin = mStartNewConversationButton.getWidth() + + lp.leftMargin + lp.rightMargin; + final int direction = AccessibilityUtil.isLayoutRtl(mStartNewConversationButton) ? -1 : 1; + getNormalizedFabAnimator().translationX(direction * fabWidthWithLeftRightMargin); + } + + public void showFab() { + if (mStartNewConversationButton == null) { + return; + } + updateHomeComposeButtonVisibility(); + getNormalizedFabAnimator().translationX(0).withEndAction(() -> { + mStartNewConversationButton.setEnabled(true); + }); + } + + @Override + public void startFullScreenPhotoViewer( + final Uri initialPhoto, final Rect initialPhotoBounds, final Uri photosUri) { + UIIntents.get().launchFullScreenPhotoViewer( + getActivity(), initialPhoto, initialPhotoBounds, photosUri); + } + + @Override + public void startFullScreenVideoViewer(final Uri videoUri) { + UIIntents.get().launchFullScreenVideoViewer(getActivity(), videoUri); + } + + @Override + public boolean isSelectionMode() { + return mHost != null && mHost.isSelectionMode(); + } + + private void setPinnedEditMode(final boolean enabled) { + if (mArchiveMode || mForwardMessageMode) { + return; + } + if (enabled) { + if (isSelectionMode() + && getActivity() instanceof AbstractConversationListActivity) { + ((AbstractConversationListActivity) getActivity()).exitMultiSelectState(); + } + if (mHomeSelectionHeader != null) { + mHomeSelectionHeader.setVisibility(View.GONE); + } + if (mHomeHeader != null) { + mHomeHeader.setVisibility(View.VISIBLE); + } + if (mHomeSelectionBar != null) { + mHomeSelectionBar.setVisibility(View.GONE); + } + } + mHomePinnedEditMode = enabled; + updateHomeEditButtonForPinnedMode(); + updateSearchBarForPinnedEditMode(); + refreshPinnedStrip(); + updateUi(); + } + + private void updateSearchBarForPinnedEditMode() { + if (mSearchBar == null) { + return; + } + cancelSearchBarAnimation(); + if (mHomePinnedEditMode) { + mSearchBarShown = false; + mSearchBar.setVisibility(View.GONE); + mSearchBar.setAlpha(1f); + mSearchBar.setTranslationY(0f); + updateListPaddingForSearchBar(); + } else { + applySearchBarVisibility(); + } + } + + private void updateHomeEditButtonForPinnedMode() { + if (mHomeEditButton == null) { + return; + } + if (mHomePinnedEditMode) { + mHomeEditButton.setVisibility(View.GONE); + if (mHomePinnedDoneButton != null) { + mHomePinnedDoneButton.setVisibility(View.VISIBLE); + mHomePinnedDoneButton.setOnClickListener(v -> setPinnedEditMode(false)); + } + } else { + mHomeEditButton.setVisibility(View.VISIBLE); + mHomeEditButton.setText(R.string.home_edit); + mHomeEditButton.setOnClickListener(this::showHomeEditPopover); + if (mHomePinnedDoneButton != null) { + mHomePinnedDoneButton.setVisibility(View.GONE); + } + } + } + + private void refreshPinnedStrip() { + if (mHomePinnedStrip == null || mArchiveMode || mForwardMessageMode + || mHomeTab != HOME_TAB_MESSAGES) { + mAdapter.setPinnedHeaderVisible(false); + return; + } + final Cursor cursor = mAdapter.getCursor(); + final boolean editMode = mHomePinnedEditMode && !isSelectionMode(); + final List pinnedIds = PinnedConversationStore.getPinnedIds(requireContext()); + HomePinnedStrip.bind(mHomePinnedStrip, cursor, pinnedIds, + editMode, isSelectionMode(), mPinnedStripListener); + final boolean showHeader = pinnedIds != null && !pinnedIds.isEmpty() + && cursor != null + && mHomePinnedStrip.getVisibility() == View.VISIBLE; + if (showHeader) { + if (!mAdapter.hasPinnedHeader()) { + mAdapter.setPinnedHeaderVisible(true); + } else { + mAdapter.notifyItemChanged(0); + } + } else { + mAdapter.setPinnedHeaderVisible(false); + } + } + + private void prunePinnedConversations(final Cursor cursor) { + if (cursor == null) { + return; + } + final Set validIds = new HashSet<>(); + final int saved = cursor.getPosition(); + for (int i = 0; i < cursor.getCount(); i++) { + if (cursor.moveToPosition(i)) { + mPinnedRowProbe.bind(cursor); + validIds.add(mPinnedRowProbe.getConversationId()); + } + } + if (saved >= 0 && saved < cursor.getCount()) { + cursor.moveToPosition(saved); + } + PinnedConversationStore.pruneMissing(requireContext(), validIds); + } + + private void showPinnedLimitDialog() { + new AlertDialog.Builder(requireContext()) + .setTitle(R.string.home_pinned_dialog_title) + .setMessage(R.string.home_pinned_dialog_message) + .setPositiveButton(R.string.home_pinned_dialog_ok, null) + .show(); + } + + private void openConversationById(final String conversationId) { + if (mHost == null) { + return; + } + final Cursor cursor = mAdapter.getCursor(); + if (cursor == null) { + return; + } + final int saved = cursor.getPosition(); + for (int i = 0; i < cursor.getCount(); i++) { + if (!cursor.moveToPosition(i)) { + continue; + } + mPinnedRowProbe.bind(cursor); + if (conversationId.equals(mPinnedRowProbe.getConversationId())) { + mHost.onConversationClick(mListBinding.getData(), mPinnedRowProbe, false, null); + break; + } + } + if (saved >= 0 && saved < cursor.getCount()) { + cursor.moveToPosition(saved); + } + } +} diff --git a/src/com/android/messaging/ui/conversationlist/ConversationListItemView.java b/app/src/main/java/com/android/messaging/ui/conversationlist/ConversationListItemView.java similarity index 73% rename from src/com/android/messaging/ui/conversationlist/ConversationListItemView.java rename to app/src/main/java/com/android/messaging/ui/conversationlist/ConversationListItemView.java index e36f782..a7c9377 100644 --- a/src/com/android/messaging/ui/conversationlist/ConversationListItemView.java +++ b/app/src/main/java/com/android/messaging/ui/conversationlist/ConversationListItemView.java @@ -33,7 +33,9 @@ import android.view.View.OnClickListener; import android.view.View.OnLayoutChangeListener; import android.view.View.OnLongClickListener; import android.view.ViewGroup; +import android.view.animation.OvershootInterpolator; import android.widget.FrameLayout; +import android.widget.ImageButton; import android.widget.ImageView; import android.widget.TextView; @@ -70,8 +72,10 @@ import java.util.List; */ public class ConversationListItemView extends FrameLayout implements OnClickListener, OnLongClickListener, OnLayoutChangeListener { - static final int UNREAD_SNIPPET_LINE_COUNT = 3; - static final int NO_UNREAD_SNIPPET_LINE_COUNT = 1; + static final int UNREAD_SNIPPET_LINE_COUNT = 2; + static final int NO_UNREAD_SNIPPET_LINE_COUNT = 2; + private static final int LIST_DIVIDER_INSET_DEFAULT_DP = 74; + private static final int LIST_DIVIDER_INSET_SELECTION_DP = 104; private int mListItemReadColor; private int mListItemUnreadColor; private Typeface mListItemReadTypeface; @@ -89,6 +93,9 @@ public class ConversationListItemView extends FrameLayout implements OnClickList final Uri photosUri); void startFullScreenVideoViewer(final Uri videoUri); boolean isSelectionMode(); + boolean shouldShowConversationPinButton(); + boolean isConversationPinned(final String conversationId); + void onConversationPinButtonClicked(final String conversationId); } private final OnClickListener fullScreenPreviewClickListener = new OnClickListener() { @@ -122,10 +129,16 @@ public class ConversationListItemView extends FrameLayout implements OnClickList private ViewGroup mCrossSwipeBackground; private ViewGroup mSwipeableContent; private TextView mConversationNameView; + private View mUnreadDotSlotView; + private View mUnreadDotView; + private TextView mCategoryChipView; private ImageView mWorkProfileIconView; private TextView mSnippetTextView; private TextView mSubjectTextView; private TextView mTimestampTextView; + private View mSelectionIndicatorView; + private View mSelectionRingView; + private ImageView mSelectionCheckView; private ContactIconView mContactIconView; private ImageView mContactCheckmarkView; private ImageView mFailedStatusIconView; @@ -133,8 +146,15 @@ public class ConversationListItemView extends FrameLayout implements OnClickList private ImageView mCrossSwipeArchiveRightImageView; private AsyncImageView mImagePreviewView; private AudioAttachmentView mAudioAttachmentView; + private ImageView mChevronView; + private ImageButton mPinButton; + private View mListDividerView; private HostInterface mHostInterface; + private static final int SELECTION_TOGGLE_ANIM_MS = 180; + private String mSelectionStateConversationId; + private Boolean mSelectionStateChecked; + public ConversationListItemView(final Context context, final AttributeSet attrs) { super(context, attrs); mData = new ConversationListItemData(); @@ -152,6 +172,12 @@ public class ConversationListItemView extends FrameLayout implements OnClickList mSubjectTextView = findViewById(R.id.conversation_subject); mWorkProfileIconView = findViewById(R.id.work_profile_icon); mTimestampTextView = findViewById(R.id.conversation_timestamp); + mUnreadDotSlotView = findViewById(R.id.conversation_unread_dot_slot); + mUnreadDotView = findViewById(R.id.conversation_unread_dot); + mCategoryChipView = findViewById(R.id.conversation_category_chip); + mSelectionIndicatorView = findViewById(R.id.conversation_selection_indicator); + mSelectionRingView = findViewById(R.id.conversation_selection_ring); + mSelectionCheckView = findViewById(R.id.conversation_selection_check); mContactIconView = findViewById(R.id.conversation_icon); mContactCheckmarkView = findViewById(R.id.conversation_checkmark); mFailedStatusIconView = findViewById(R.id.conversation_failed_status_icon); @@ -159,13 +185,16 @@ public class ConversationListItemView extends FrameLayout implements OnClickList mCrossSwipeArchiveRightImageView = findViewById(R.id.crossSwipeArchiveIconRight); mImagePreviewView = findViewById(R.id.conversation_image_preview); mAudioAttachmentView = findViewById(R.id.audio_attachment_view); + mChevronView = findViewById(R.id.conversation_chevron); + mPinButton = findViewById(R.id.conversation_pin_button); + mListDividerView = findViewById(R.id.conversation_list_divider); mConversationNameView.addOnLayoutChangeListener(this); mSnippetTextView.addOnLayoutChangeListener(this); final Resources resources = getContext().getResources(); final Resources.Theme theme = getContext().getTheme(); - mListItemReadColor = resources.getColor(R.color.conversation_list_item_read, theme); - mListItemUnreadColor = resources.getColor(R.color.conversation_list_item_unread, theme); + mListItemReadColor = resources.getColor(R.color.home_text_primary, theme); + mListItemUnreadColor = resources.getColor(R.color.home_text_primary, theme); mListItemReadTypeface = Typefaces.getRobotoNormal(); mListItemUnreadTypeface = Typefaces.getRobotoBold(); @@ -188,10 +217,34 @@ public class ConversationListItemView extends FrameLayout implements OnClickList private void setWorkProfileIcon() { mWorkProfileIconView.setVisibility(mData.isEnterprise() ? View.VISIBLE : View.GONE); + if (mCategoryChipView != null) { + final boolean selectionMode = + mHostInterface != null && mHostInterface.isSelectionMode(); + if (selectionMode) { + mCategoryChipView.setVisibility(View.GONE); + } else { + mCategoryChipView.setVisibility(View.VISIBLE); + mCategoryChipView.setText(mData.isEnterprise() + ? R.string.home_chip_work + : R.string.home_chip_personal); + } + } } private void setConversationName() { - if (mData.getIsRead() || mData.getShowDraft()) { + final boolean selectionMode = + mHostInterface != null && mHostInterface.isSelectionMode(); + final boolean showUnreadDot = !mData.getIsRead() && !mData.getShowDraft(); + if (mUnreadDotSlotView != null) { + mUnreadDotSlotView.setVisibility(View.VISIBLE); + } + if (mUnreadDotView != null) { + mUnreadDotView.setVisibility(showUnreadDot ? View.VISIBLE : View.INVISIBLE); + } + if (selectionMode) { + mConversationNameView.setTextColor(mListItemReadColor); + mConversationNameView.setTypeface(mListItemUnreadTypeface); + } else if (mData.getIsRead() || mData.getShowDraft()) { mConversationNameView.setTextColor(mListItemReadColor); mConversationNameView.setTypeface(mListItemReadTypeface); } else { @@ -250,6 +303,134 @@ public class ConversationListItemView extends FrameLayout implements OnClickList mSnippetTextView.setText(getSnippetText()); } + private void updateSelectionIndicator(final boolean selectionMode, final boolean isSelected, + final Resources resources) { + if (mSelectionIndicatorView == null || mSelectionRingView == null + || mSelectionCheckView == null) { + return; + } + if (!selectionMode) { + mSelectionIndicatorView.animate().cancel(); + mSelectionCheckView.animate().cancel(); + mSelectionIndicatorView.setScaleX(1f); + mSelectionIndicatorView.setScaleY(1f); + mSelectionCheckView.setAlpha(1f); + mSelectionCheckView.setScaleX(1f); + mSelectionCheckView.setScaleY(1f); + mSelectionIndicatorView.setVisibility(GONE); + mSelectionStateConversationId = null; + mSelectionStateChecked = null; + return; + } + mSelectionIndicatorView.setVisibility(VISIBLE); + final String conversationId = mData.getConversationId(); + final boolean sameConversation = conversationId != null + && conversationId.equals(mSelectionStateConversationId); + final boolean animateToggle = sameConversation && mSelectionStateChecked != null + && mSelectionStateChecked.booleanValue() != isSelected; + mSelectionStateConversationId = conversationId; + mSelectionStateChecked = isSelected; + + mSelectionIndicatorView.animate().cancel(); + mSelectionCheckView.animate().cancel(); + + if (isSelected) { + mSelectionRingView.setBackground(resources.getDrawable( + R.drawable.home_bg_selection_ring_checked, getContext().getTheme())); + mSelectionCheckView.setVisibility(VISIBLE); + if (animateToggle) { + mSelectionIndicatorView.setScaleX(0.88f); + mSelectionIndicatorView.setScaleY(0.88f); + mSelectionIndicatorView.animate() + .scaleX(1f) + .scaleY(1f) + .setDuration(SELECTION_TOGGLE_ANIM_MS) + .setInterpolator(new OvershootInterpolator(1.6f)); + mSelectionCheckView.setAlpha(0f); + mSelectionCheckView.setScaleX(0.4f); + mSelectionCheckView.setScaleY(0.4f); + mSelectionCheckView.animate() + .alpha(1f) + .scaleX(1f) + .scaleY(1f) + .setDuration(SELECTION_TOGGLE_ANIM_MS) + .setInterpolator(UiUtils.DEFAULT_INTERPOLATOR); + } else { + mSelectionIndicatorView.setScaleX(1f); + mSelectionIndicatorView.setScaleY(1f); + mSelectionCheckView.setAlpha(1f); + mSelectionCheckView.setScaleX(1f); + mSelectionCheckView.setScaleY(1f); + } + } else { + mSelectionRingView.setBackground(resources.getDrawable( + R.drawable.home_bg_selection_ring, getContext().getTheme())); + mSelectionCheckView.setVisibility(GONE); + mSelectionCheckView.setAlpha(1f); + mSelectionCheckView.setScaleX(1f); + mSelectionCheckView.setScaleY(1f); + if (animateToggle) { + mSelectionIndicatorView.setScaleX(0.92f); + mSelectionIndicatorView.setScaleY(0.92f); + mSelectionIndicatorView.animate() + .scaleX(1f) + .scaleY(1f) + .setDuration(SELECTION_TOGGLE_ANIM_MS) + .setInterpolator(UiUtils.DEFAULT_INTERPOLATOR); + } else { + mSelectionIndicatorView.setScaleX(1f); + mSelectionIndicatorView.setScaleY(1f); + } + } + } + + private void updatePinButton(final boolean selectionMode, final Resources resources) { + if (mPinButton == null || mHostInterface == null) { + return; + } + final boolean showPin = mHostInterface.shouldShowConversationPinButton() + && !selectionMode; + if (!showPin) { + mPinButton.setVisibility(GONE); + if (mChevronView != null) { + mChevronView.setVisibility(selectionMode ? GONE : VISIBLE); + } + return; + } + mPinButton.setVisibility(VISIBLE); + if (mChevronView != null) { + mChevronView.setVisibility(GONE); + } + final boolean pinned = mHostInterface.isConversationPinned(mData.getConversationId()); + mPinButton.setBackground(resources.getDrawable( + pinned ? R.drawable.home_bg_pin_active : R.drawable.home_bg_pin_inactive, + getContext().getTheme())); + mPinButton.setColorFilter(resources.getColor( + pinned ? android.R.color.white : R.color.home_text_secondary, + getContext().getTheme())); + mPinButton.setContentDescription(resources.getString( + pinned ? R.string.home_unpin_content_description + : R.string.home_pin_content_description)); + mPinButton.setOnClickListener(v -> mHostInterface.onConversationPinButtonClicked( + mData.getConversationId())); + } + + private void updateListDividerInset(final boolean selectionMode) { + if (mListDividerView == null) { + return; + } + final ViewGroup.MarginLayoutParams layoutParams = + (ViewGroup.MarginLayoutParams) mListDividerView.getLayoutParams(); + final int insetDp = selectionMode ? LIST_DIVIDER_INSET_SELECTION_DP + : LIST_DIVIDER_INSET_DEFAULT_DP; + final float density = getResources().getDisplayMetrics().density; + final int insetPx = (int) (insetDp * density + 0.5f); + if (layoutParams.leftMargin != insetPx) { + layoutParams.leftMargin = insetPx; + mListDividerView.setLayoutParams(layoutParams); + } + } + // Resource Ids of content descriptions prefixes for different message status. private static final int [][][] sPrimaryContentDescriptions = { // 1:1 conversation @@ -379,15 +560,18 @@ public class ConversationListItemView extends FrameLayout implements OnClickList final int typefaceStyle = mData.getShowDraft() ? Typeface.ITALIC : Typeface.NORMAL; final String snippetText = getSnippetText(); - if (mData.getIsRead() || mData.getShowDraft()) { + final boolean selectionMode = mHostInterface.isSelectionMode(); + if (selectionMode) { + maxLines = 0; + typeface = mListItemReadTypeface; + } else if (mData.getIsRead() || mData.getShowDraft()) { maxLines = TextUtils.isEmpty(snippetText) ? 0 : NO_UNREAD_SNIPPET_LINE_COUNT; - color = mListItemReadColor; typeface = mListItemReadTypeface; } else { maxLines = TextUtils.isEmpty(snippetText) ? 0 : UNREAD_SNIPPET_LINE_COUNT; - color = mListItemUnreadColor; typeface = mListItemUnreadTypeface; } + color = getResources().getColor(R.color.home_text_secondary, getContext().getTheme()); mSnippetTextView.setMaxLines(maxLines); mSnippetTextView.setTextColor(color); @@ -395,9 +579,15 @@ public class ConversationListItemView extends FrameLayout implements OnClickList mSubjectTextView.setTextColor(color); mSubjectTextView.setTypeface(typeface, typefaceStyle); - setSnippet(); + if (selectionMode) { + mSnippetTextView.setVisibility(GONE); + mSubjectTextView.setVisibility(GONE); + } else { + mSnippetTextView.setVisibility(VISIBLE); + setSnippet(); + setSubject(); + } setConversationName(); - setSubject(); setWorkProfileIcon(); setContentDescription(buildContentDescription(resources, mData, mConversationNameView.getPaint())); @@ -420,12 +610,14 @@ public class ConversationListItemView extends FrameLayout implements OnClickList // row is left with a latest_message_id of a no longer existing message and // therefore the join values come back as null (or in this case zero). || mData.getMessageStatus() == MessageData.BUGLE_STATUS_UNKNOWN) { - mTimestampTextView.setTextColor(mListItemReadColor); + mTimestampTextView.setTextColor(resources.getColor(R.color.home_text_secondary, + getContext().getTheme())); mTimestampTextView.setTypeface(mListItemReadTypeface, typefaceStyle); mTimestampTextView.setText(resources.getString( R.string.conversation_list_item_view_draft_message)); } else { - mTimestampTextView.setTextColor(mListItemReadColor); + mTimestampTextView.setTextColor(resources.getColor(R.color.home_text_secondary, + getContext().getTheme())); mTimestampTextView.setTypeface(mListItemReadTypeface, typefaceStyle); final String formattedTimestamp = mData.getFormattedTimestamp(); if (mData.getIsSendRequested()) { @@ -438,19 +630,17 @@ public class ConversationListItemView extends FrameLayout implements OnClickList final boolean isSelected = mHostInterface.isConversationSelected(mData.getConversationId()); setSelected(isSelected); Uri iconUri = null; - int contactIconVisibility = GONE; + int contactIconVisibility = VISIBLE; int checkmarkVisiblity = GONE; int failStatusVisiblity = GONE; - if (isSelected) { - checkmarkVisiblity = VISIBLE; - } else { - contactIconVisibility = VISIBLE; + if (!isSelected) { // Only show the fail icon if it is not a group conversation. // And also require that we be the default sms app. if (mData.getIsFailedStatus() && !mData.getIsGroup() && isDefaultSmsApp) { failStatusVisiblity = VISIBLE; } } + updateSelectionIndicator(selectionMode, isSelected, resources); if (mData.getIcon() != null) { iconUri = Uri.parse(mData.getIcon()); } @@ -464,6 +654,9 @@ public class ConversationListItemView extends FrameLayout implements OnClickList mContactCheckmarkView.setVisibility(checkmarkVisiblity); mFailedStatusIconView.setVisibility(failStatusVisiblity); + updatePinButton(selectionMode, resources); + updateListDividerInset(selectionMode); + final Uri previewUri = mData.getShowDraft() ? mData.getDraftPreviewUri() : mData.getPreviewUri(); final String previewContentType = mData.getShowDraft() ? diff --git a/src/com/android/messaging/ui/conversationlist/ConversationListSwipeHelper.java b/app/src/main/java/com/android/messaging/ui/conversationlist/ConversationListSwipeHelper.java similarity index 100% rename from src/com/android/messaging/ui/conversationlist/ConversationListSwipeHelper.java rename to app/src/main/java/com/android/messaging/ui/conversationlist/ConversationListSwipeHelper.java diff --git a/src/com/android/messaging/ui/conversationlist/ForwardMessageActivity.java b/app/src/main/java/com/android/messaging/ui/conversationlist/ForwardMessageActivity.java similarity index 100% rename from src/com/android/messaging/ui/conversationlist/ForwardMessageActivity.java rename to app/src/main/java/com/android/messaging/ui/conversationlist/ForwardMessageActivity.java diff --git a/src/com/android/messaging/ui/conversationlist/MultiSelectActionModeCallback.java b/app/src/main/java/com/android/messaging/ui/conversationlist/MultiSelectActionModeCallback.java similarity index 88% rename from src/com/android/messaging/ui/conversationlist/MultiSelectActionModeCallback.java rename to app/src/main/java/com/android/messaging/ui/conversationlist/MultiSelectActionModeCallback.java index fde8c59..2939cdb 100644 --- a/src/com/android/messaging/ui/conversationlist/MultiSelectActionModeCallback.java +++ b/app/src/main/java/com/android/messaging/ui/conversationlist/MultiSelectActionModeCallback.java @@ -41,6 +41,7 @@ public class MultiSelectActionModeCallback implements Callback { void onActionBarAddContact(final SelectedConversation conversation); void onActionBarBlock(final SelectedConversation conversation); void onActionBarHome(); + void onSelectionCountChanged(int count); } static class SelectedConversation { @@ -63,6 +64,7 @@ public class MultiSelectActionModeCallback implements Callback { } private final ArrayMap mSelectedConversations; + private final boolean mUseHomeSelectionChrome; private Listener mListener; private MenuItem mArchiveMenuItem; @@ -72,13 +74,30 @@ public class MultiSelectActionModeCallback implements Callback { private boolean mHasInflated; public MultiSelectActionModeCallback(final Listener listener) { + this(listener, false); + } + + public MultiSelectActionModeCallback(final Listener listener, + final boolean useHomeSelectionChrome) { mListener = listener; + mUseHomeSelectionChrome = useHomeSelectionChrome; mSelectedConversations = new ArrayMap<>(); } + public boolean useHomeSelectionChrome() { + return mUseHomeSelectionChrome; + } + @Override public boolean onCreateActionMode(ActionMode actionMode, Menu menu) { + if (mUseHomeSelectionChrome) { + mHasInflated = false; + if (mListener != null) { + mListener.onSelectionCountChanged(mSelectedConversations.size()); + } + return true; + } actionMode.getMenuInflater().inflate(R.menu.conversation_list_fragment_select_menu, menu); mArchiveMenuItem = menu.findItem(R.id.action_archive); mUnarchiveMenuItem = menu.findItem(R.id.action_unarchive); @@ -139,10 +158,13 @@ public class MultiSelectActionModeCallback implements Callback { mSelectedConversations.put(id, new SelectedConversation(conversationListItemData)); } - if (mSelectedConversations.isEmpty()) { + if (mSelectedConversations.isEmpty() && !mUseHomeSelectionChrome) { mListener.onActionBarHome(); } else { updateActionIconsVisiblity(); + if (mListener != null) { + mListener.onSelectionCountChanged(mSelectedConversations.size()); + } } } @@ -150,6 +172,10 @@ public class MultiSelectActionModeCallback implements Callback { return mSelectedConversations.containsKey(selectedId); } + public Collection getSelectedConversations() { + return mSelectedConversations.values(); + } + private void updateActionIconsVisiblity() { if (!mHasInflated) { return; diff --git a/src/com/android/messaging/ui/conversationlist/ShareIntentActivity.java b/app/src/main/java/com/android/messaging/ui/conversationlist/ShareIntentActivity.java similarity index 100% rename from src/com/android/messaging/ui/conversationlist/ShareIntentActivity.java rename to app/src/main/java/com/android/messaging/ui/conversationlist/ShareIntentActivity.java diff --git a/src/com/android/messaging/ui/conversationlist/ShareIntentAdapter.java b/app/src/main/java/com/android/messaging/ui/conversationlist/ShareIntentAdapter.java similarity index 100% rename from src/com/android/messaging/ui/conversationlist/ShareIntentAdapter.java rename to app/src/main/java/com/android/messaging/ui/conversationlist/ShareIntentAdapter.java diff --git a/src/com/android/messaging/ui/conversationlist/ShareIntentFragment.java b/app/src/main/java/com/android/messaging/ui/conversationlist/ShareIntentFragment.java similarity index 100% rename from src/com/android/messaging/ui/conversationlist/ShareIntentFragment.java rename to app/src/main/java/com/android/messaging/ui/conversationlist/ShareIntentFragment.java diff --git a/src/com/android/messaging/ui/conversationsettings/CopyContactDetailDialog.java b/app/src/main/java/com/android/messaging/ui/conversationsettings/CopyContactDetailDialog.java similarity index 100% rename from src/com/android/messaging/ui/conversationsettings/CopyContactDetailDialog.java rename to app/src/main/java/com/android/messaging/ui/conversationsettings/CopyContactDetailDialog.java diff --git a/src/com/android/messaging/ui/conversationsettings/PeopleAndOptionsActivity.java b/app/src/main/java/com/android/messaging/ui/conversationsettings/PeopleAndOptionsActivity.java similarity index 100% rename from src/com/android/messaging/ui/conversationsettings/PeopleAndOptionsActivity.java rename to app/src/main/java/com/android/messaging/ui/conversationsettings/PeopleAndOptionsActivity.java diff --git a/src/com/android/messaging/ui/conversationsettings/PeopleAndOptionsFragment.java b/app/src/main/java/com/android/messaging/ui/conversationsettings/PeopleAndOptionsFragment.java similarity index 100% rename from src/com/android/messaging/ui/conversationsettings/PeopleAndOptionsFragment.java rename to app/src/main/java/com/android/messaging/ui/conversationsettings/PeopleAndOptionsFragment.java diff --git a/src/com/android/messaging/ui/conversationsettings/PeopleOptionsItemView.java b/app/src/main/java/com/android/messaging/ui/conversationsettings/PeopleOptionsItemView.java similarity index 100% rename from src/com/android/messaging/ui/conversationsettings/PeopleOptionsItemView.java rename to app/src/main/java/com/android/messaging/ui/conversationsettings/PeopleOptionsItemView.java diff --git a/app/src/main/java/com/android/messaging/ui/home/HomeContactListAdapter.java b/app/src/main/java/com/android/messaging/ui/home/HomeContactListAdapter.java new file mode 100644 index 0000000..fbeb9ea --- /dev/null +++ b/app/src/main/java/com/android/messaging/ui/home/HomeContactListAdapter.java @@ -0,0 +1,34 @@ +package com.android.messaging.ui.home; + +import android.content.Context; +import android.database.Cursor; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.CursorAdapter; + +import com.android.messaging.R; +import com.android.messaging.ui.contact.ContactListItemView; +import com.android.messaging.util.Assert; + +public class HomeContactListAdapter extends CursorAdapter { + private final ContactListItemView.HostInterface mHost; + + public HomeContactListAdapter(final Context context, final Cursor cursor, + final ContactListItemView.HostInterface host) { + super(context, cursor, 0); + mHost = host; + } + + @Override + public void bindView(final View view, final Context context, final Cursor cursor) { + Assert.isTrue(view instanceof ContactListItemView); + ((ContactListItemView) view).bind(cursor, mHost, false, null); + } + + @Override + public View newView(final Context context, final Cursor cursor, final ViewGroup parent) { + return LayoutInflater.from(context).inflate(R.layout.home_contacts_list_item, parent, + false); + } +} diff --git a/app/src/main/java/com/android/messaging/ui/home/HomeContactsFragment.java b/app/src/main/java/com/android/messaging/ui/home/HomeContactsFragment.java new file mode 100644 index 0000000..1181dce --- /dev/null +++ b/app/src/main/java/com/android/messaging/ui/home/HomeContactsFragment.java @@ -0,0 +1,148 @@ +package com.android.messaging.ui.home; + +import android.database.Cursor; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ListView; +import android.widget.Toast; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; +import androidx.loader.app.LoaderManager; + +import com.android.messaging.R; +import com.android.messaging.datamodel.DataModel; +import com.android.messaging.datamodel.action.GetOrCreateConversationAction; +import com.android.messaging.datamodel.action.ActionMonitor; +import com.android.messaging.datamodel.action.GetOrCreateConversationAction.GetOrCreateConversationActionListener; +import com.android.messaging.datamodel.action.GetOrCreateConversationAction.GetOrCreateConversationActionMonitor; +import com.android.messaging.util.Assert; +import com.android.messaging.util.Assert.RunsOnMainThread; +import com.android.messaging.datamodel.binding.Binding; +import com.android.messaging.datamodel.binding.BindingBase; +import com.android.messaging.datamodel.data.ContactListItemData; +import com.android.messaging.datamodel.data.ContactPickerData; +import com.android.messaging.datamodel.data.ContactPickerData.ContactPickerDataListener; +import com.android.messaging.datamodel.data.ParticipantData; +import com.android.messaging.ui.UIIntents; +import com.android.messaging.ui.contact.ContactListItemView; +import com.android.messaging.util.ContactUtil; +import com.android.messaging.util.LogUtil; + +import java.util.ArrayList; + +public class HomeContactsFragment extends Fragment implements ContactPickerDataListener, + ContactListItemView.HostInterface, GetOrCreateConversationActionListener { + + private final Binding mBinding = BindingBase.createBinding(this); + private HomeContactListAdapter mAdapter; + private GetOrCreateConversationActionMonitor mMonitor; + + @Override + public void onCreate(@Nullable final Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + if (ContactUtil.hasReadContactsPermission()) { + mBinding.bind(DataModel.get().createContactPickerData(requireContext(), this)); + mBinding.getData().init(LoaderManager.getInstance(this), mBinding); + } + } + + @Nullable + @Override + public View onCreateView(@NonNull final LayoutInflater inflater, + @Nullable final ViewGroup container, @Nullable final Bundle savedInstanceState) { + return inflater.inflate(R.layout.home_contacts_fragment, container, false); + } + + @Override + public void onViewCreated(@NonNull final View view, @Nullable final Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + final ListView listView = view.findViewById(R.id.home_contacts_list); + mAdapter = new HomeContactListAdapter(requireContext(), null, this); + listView.setAdapter(mAdapter); + + view.findViewById(R.id.home_contacts_search).setOnClickListener(v -> + Toast.makeText(requireContext(), R.string.home_popover_coming_soon, + Toast.LENGTH_SHORT).show()); + view.findViewById(R.id.home_contacts_invite).setOnClickListener(v -> + Toast.makeText(requireContext(), R.string.home_popover_coming_soon, + Toast.LENGTH_SHORT).show()); + view.findViewById(R.id.home_contacts_recent_calls).setOnClickListener(v -> + Toast.makeText(requireContext(), R.string.home_popover_coming_soon, + Toast.LENGTH_SHORT).show()); + view.findViewById(R.id.home_contacts_sort).setOnClickListener(v -> + Toast.makeText(requireContext(), R.string.home_popover_coming_soon, + Toast.LENGTH_SHORT).show()); + view.findViewById(R.id.home_contacts_add).setOnClickListener(v -> + UIIntents.get().launchCreateNewConversationActivity(requireActivity(), null)); + } + + @Override + public void onDestroy() { + super.onDestroy(); + if (mBinding.isBound()) { + mBinding.unbind(); + } + if (mMonitor != null) { + mMonitor.unregister(); + mMonitor = null; + } + } + + @Override + public void onAllContactsCursorUpdated(final Cursor data) { + mBinding.ensureBound(); + mAdapter.changeCursor(data); + } + + @Override + public void onFrequentContactsCursorUpdated(final Cursor data) { + // All contacts list only. + } + + @Override + public void onContactCustomColorLoaded(final ContactPickerData data) { + mBinding.ensureBound(data); + mAdapter.notifyDataSetChanged(); + } + + @Override + public void onContactListItemClicked(final ContactListItemData item, + final ContactListItemView view) { + if (mMonitor != null) { + return; + } + final ArrayList participants = new ArrayList<>(1); + participants.add(ParticipantData.getFromRecipientEntry(item.getRecipientEntry())); + mMonitor = GetOrCreateConversationAction.getOrCreateConversation(participants, null, + this); + } + + @Override + public boolean isContactSelected(final ContactListItemData item) { + return false; + } + + @Override + @RunsOnMainThread + public void onGetOrCreateConversationSucceeded(final ActionMonitor monitor, + final Object data, final String conversationId) { + Assert.isTrue(monitor == mMonitor); + mMonitor = null; + if (conversationId != null) { + UIIntents.get().launchConversationActivity(requireActivity(), conversationId, null, + null, false); + } + } + + @Override + @RunsOnMainThread + public void onGetOrCreateConversationFailed(final ActionMonitor monitor, final Object data) { + Assert.isTrue(monitor == mMonitor); + LogUtil.e(LogUtil.BUGLE_TAG, "HomeContactsFragment onGetOrCreateConversationFailed"); + mMonitor = null; + } +} diff --git a/app/src/main/java/com/android/messaging/ui/home/HomePinnedStrip.java b/app/src/main/java/com/android/messaging/ui/home/HomePinnedStrip.java new file mode 100644 index 0000000..bb1285a --- /dev/null +++ b/app/src/main/java/com/android/messaging/ui/home/HomePinnedStrip.java @@ -0,0 +1,418 @@ +/* + * Copyright (C) 2025 The LineageOS Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.messaging.ui.home; + +import android.content.Context; +import android.content.res.Resources; +import android.database.Cursor; +import android.net.Uri; +import android.text.TextUtils; +import android.animation.LayoutTransition; +import android.animation.ObjectAnimator; +import android.animation.ValueAnimator; +import android.view.Gravity; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.animation.LinearInterpolator; +import android.widget.FrameLayout; +import android.widget.ImageButton; +import android.widget.LinearLayout; +import android.widget.TextView; + +import com.android.messaging.R; +import com.android.messaging.datamodel.data.ConversationListItemData; +import com.android.messaging.ui.ContactIconView; +import com.android.messaging.util.PhoneUtils; + +import android.support.v7.mms.pdu.ContentType; + +import java.util.ArrayList; +import java.util.List; + +/** Renders the pinned-conversation grid above the message list. */ +public final class HomePinnedStrip { + + private static final float JIGGLE_DEGREES = 2.5f; + private static final float PINNED_AVATAR_SCALE = 0.76f; + private static final int COLUMN_COUNT = 3; + + public interface Listener { + void onPinnedConversationClicked(String conversationId); + + void onPinnedConversationUnpin(String conversationId); + } + + private HomePinnedStrip() { + } + + public static void bind(final View stripRoot, final Cursor cursor, + final List pinnedIds, final boolean editMode, final boolean selectionMode, + final Listener listener) { + if (stripRoot == null) { + return; + } + final LinearLayout rows = stripRoot.findViewById(R.id.home_pinned_rows); + if (rows == null) { + return; + } + if (rows.getLayoutTransition() == null) { + final LayoutTransition transition = new LayoutTransition(); + transition.setDuration(200); + transition.enableTransitionType(LayoutTransition.APPEARING); + transition.enableTransitionType(LayoutTransition.DISAPPEARING); + transition.enableTransitionType(LayoutTransition.CHANGE_APPEARING); + transition.enableTransitionType(LayoutTransition.CHANGE_DISAPPEARING); + rows.setLayoutTransition(transition); + } + rows.removeAllViews(); + if (pinnedIds == null || pinnedIds.isEmpty() || cursor == null) { + stripRoot.setVisibility(View.GONE); + return; + } + final ConversationListItemData row = new ConversationListItemData(); + boolean hasAny = false; + final Context context = stripRoot.getContext(); + final LayoutInflater inflater = LayoutInflater.from(context); + final int avatarSizePx = computePinnedAvatarSizePx(context); + LinearLayout currentRow = null; + int column = 0; + int itemIndex = 0; + final List jiggleTargets = new ArrayList<>(); + for (final String id : pinnedIds) { + if (!bindRow(cursor, id, row)) { + continue; + } + hasAny = true; + if (column == 0) { + currentRow = newRow(context, rows.getChildCount() > 0); + rows.addView(currentRow); + } + final View item = inflater.inflate(R.layout.home_pinned_item, currentRow, false); + final LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams( + 0, LinearLayout.LayoutParams.WRAP_CONTENT, 1f); + lp.gravity = Gravity.TOP | Gravity.CENTER_HORIZONTAL; + item.setLayoutParams(lp); + + final View pinnedCell = item.findViewById(R.id.home_pinned_cell); + final View avatarStack = item.findViewById(R.id.home_pinned_avatar_stack); + final ContactIconView icon = item.findViewById(R.id.home_pinned_icon); + final TextView label = item.findViewById(R.id.home_pinned_label); + final View previewContainer = item.findViewById(R.id.home_pinned_preview_container); + final TextView preview = item.findViewById(R.id.home_pinned_preview); + final View unreadDot = item.findViewById(R.id.home_pinned_unread_dot); + final ImageButton remove = item.findViewById(R.id.home_pinned_remove); + applyPinnedItemInsets(context, item, pinnedCell, editMode); + applyPinnedCellLayout(pinnedCell, avatarSizePx, context.getResources()); + applyPinnedAvatarSize(avatarStack, icon, avatarSizePx); + applyPinnedPreviewPosition(previewContainer, avatarSizePx, context.getResources()); + applyPinnedPreviewMaxWidth(preview, context, item); + Uri iconUri = null; + if (row.getIcon() != null) { + iconUri = Uri.parse(row.getIcon()); + } + icon.setImageResourceUri(iconUri, row.getParticipantContactId(), + row.getParticipantLookupKey(), row.getOtherParticipantNormalizedDestination()); + label.setText(labelForPinnedRow(row, editMode)); + bindUnreadPreview(context, row, editMode, selectionMode, previewContainer, preview, + unreadDot); + if (editMode) { + remove.setVisibility(View.VISIBLE); + remove.bringToFront(); + remove.setElevation(4f); + remove.setOnClickListener(v -> { + if (listener != null) { + listener.onPinnedConversationUnpin(id); + } + }); + item.setOnClickListener(null); + jiggleTargets.add(avatarStack); + } else { + stopEditJiggle(avatarStack); + remove.setVisibility(View.GONE); + item.setOnClickListener(v -> { + if (listener != null) { + listener.onPinnedConversationClicked(id); + } + }); + } + currentRow.addView(item); + itemIndex++; + column++; + if (column >= COLUMN_COUNT) { + column = 0; + } + } + padRow(currentRow, column); + if (hasAny) { + stripRoot.setVisibility(View.VISIBLE); + } else { + stripRoot.setVisibility(View.GONE); + stripRoot.setMinimumHeight(0); + } + if (editMode && !jiggleTargets.isEmpty()) { + stripRoot.post(() -> { + for (int i = 0; i < jiggleTargets.size(); i++) { + startEditJiggle(jiggleTargets.get(i), i); + } + }); + } + } + + private static CharSequence labelForPinnedRow(final ConversationListItemData row, + final boolean editMode) { + if (editMode) { + return row.getName(); + } + if (!row.getIsGroup()) { + final String destination = row.getOtherParticipantNormalizedDestination(); + if (!TextUtils.isEmpty(destination)) { + return PhoneUtils.getDefault().formatForDisplay(destination); + } + } + return row.getName(); + } + + /** Avatar keeps a square box centered in the grid cell, on the shared bottom baseline. */ + private static void applyPinnedAvatarSize(final View avatarStack, final ContactIconView icon, + final int avatarSizePx) { + if (avatarStack != null) { + final FrameLayout.LayoutParams stackLp = + new FrameLayout.LayoutParams(avatarSizePx, avatarSizePx); + stackLp.gravity = Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL; + avatarStack.setLayoutParams(stackLp); + } + if (icon != null) { + icon.setLayoutParams(new FrameLayout.LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.MATCH_PARENT)); + } + } + + /** Same cell height and avatar baseline for every column (preview does not shift avatar). */ + private static void applyPinnedCellLayout(final View pinnedCell, final int avatarSizePx, + final Resources res) { + if (pinnedCell == null) { + return; + } + final int previewBandPx = res.getDimensionPixelSize(R.dimen.home_pinned_preview_top_inset); + final ViewGroup.LayoutParams cellLp = pinnedCell.getLayoutParams(); + if (cellLp != null) { + cellLp.height = avatarSizePx + previewBandPx; + pinnedCell.setLayoutParams(cellLp); + } + pinnedCell.setMinimumHeight(avatarSizePx + previewBandPx); + pinnedCell.setPadding(0, 0, 0, 0); + } + + /** Preview shares the avatar center and its tail sinks into the avatar's top edge. */ + private static void applyPinnedPreviewPosition(final View previewContainer, + final int avatarSizePx, final Resources res) { + if (previewContainer == null) { + return; + } + final ViewGroup.LayoutParams raw = previewContainer.getLayoutParams(); + if (!(raw instanceof FrameLayout.LayoutParams)) { + return; + } + final FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) raw; + lp.gravity = Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL; + final int overlapPx = res.getDimensionPixelSize( + R.dimen.home_pinned_preview_avatar_overlap); + lp.bottomMargin = Math.max(0, avatarSizePx - overlapPx); + lp.setMarginStart(0); + lp.setMarginEnd(0); + lp.topMargin = 0; + previewContainer.setLayoutParams(lp); + } + + private static void applyPinnedPreviewMaxWidth(final TextView preview, final Context context, + final View item) { + if (preview == null) { + return; + } + final Resources res = context.getResources(); + final float density = res.getDisplayMetrics().density; + final int maxDimen = res.getDimensionPixelSize(R.dimen.home_pinned_preview_max_width); + final int columnPx = computePinnedColumnWidthPx(context); + final int itemPad = res.getDimensionPixelSize(R.dimen.looply_space_xs); + final int inset = res.getDimensionPixelSize(R.dimen.home_pinned_preview_column_inset); + final int fromColumn = columnPx - item.getPaddingLeft() - item.getPaddingRight() - inset; + final int maxPx = Math.min(maxDimen, Math.max(0, fromColumn)); + preview.setMaxWidth(Math.max((int) (56 * density), maxPx)); + } + + public static int computePinnedColumnWidthPx(final Context context) { + final Resources res = context.getResources(); + final float density = res.getDisplayMetrics().density; + final int screenPx = res.getDisplayMetrics().widthPixels; + final int stripPadPx = (int) (24 * density); + return Math.max(0, (screenPx - stripPadPx) / COLUMN_COUNT); + } + + public static int computePinnedAvatarSizePx(final Context context) { + final float density = context.getResources().getDisplayMetrics().density; + final int columnPx = computePinnedColumnWidthPx(context); + int avatarPx = (int) (columnPx * PINNED_AVATAR_SCALE); + final int minPx = (int) (64 * density); + final int maxPx = (int) (104 * density); + return Math.max(minPx, Math.min(maxPx, avatarPx)); + } + + private static void applyPinnedItemInsets(final Context context, final View item, + final View pinnedCell, final boolean editMode) { + final Resources res = context.getResources(); + final int tight = res.getDimensionPixelSize(R.dimen.looply_space_xs); + if (editMode) { + final int jiggle = res.getDimensionPixelSize(R.dimen.home_pinned_jiggle_inset); + item.setPadding(jiggle, jiggle, jiggle, tight); + } else { + item.setPadding(tight, tight, tight, + res.getDimensionPixelSize(R.dimen.looply_space_sm)); + } + } + + private static void bindUnreadPreview(final Context context, + final ConversationListItemData row, final boolean editMode, + final boolean selectionMode, final View previewContainer, final TextView preview, + final View unreadDot) { + final boolean unread = !row.getIsRead() && !row.getShowDraft(); + if (unreadDot != null) { + unreadDot.setVisibility(unread && !editMode ? View.VISIBLE : View.INVISIBLE); + } + if (previewContainer != null) { + previewContainer.setTranslationX(0f); + } + if (editMode || selectionMode || previewContainer == null || preview == null) { + if (previewContainer != null) { + previewContainer.setVisibility(View.GONE); + } + return; + } + final String snippet = unreadPreviewText(context, row); + if (TextUtils.isEmpty(snippet)) { + previewContainer.setVisibility(View.GONE); + return; + } + preview.setText(snippet); + previewContainer.setVisibility(View.VISIBLE); + } + + private static String unreadPreviewText(final Context context, + final ConversationListItemData row) { + if (row.getIsRead() || row.getShowDraft()) { + return null; + } + String snippet = row.getSnippetText(); + final String previewContentType = row.getPreviewContentType(); + if (TextUtils.isEmpty(snippet)) { + final Resources resources = context.getResources(); + if (ContentType.isAudioType(previewContentType)) { + snippet = resources.getString(R.string.conversation_list_snippet_audio_clip); + } else if (ContentType.isImageType(previewContentType)) { + snippet = resources.getString(R.string.conversation_list_snippet_picture); + } else if (ContentType.isVideoType(previewContentType)) { + snippet = resources.getString(R.string.conversation_list_snippet_video); + } else if (ContentType.isVCardType(previewContentType)) { + snippet = resources.getString(R.string.conversation_list_snippet_vcard); + } + } + return snippet; + } + + private static LinearLayout newRow(final Context context, final boolean addTopSpacing) { + final LinearLayout row = new LinearLayout(context); + row.setOrientation(LinearLayout.HORIZONTAL); + row.setClipChildren(false); + row.setClipToPadding(false); + final LinearLayout.LayoutParams rowLp = new LinearLayout.LayoutParams( + LinearLayout.LayoutParams.MATCH_PARENT, + LinearLayout.LayoutParams.WRAP_CONTENT); + if (addTopSpacing) { + rowLp.topMargin = context.getResources().getDimensionPixelSize( + R.dimen.home_pinned_row_spacing); + } + row.setLayoutParams(rowLp); + return row; + } + + /** Keeps three-column alignment when the last row is not full. */ + private static void padRow(final LinearLayout row, final int filledColumns) { + if (row == null || filledColumns == 0 || filledColumns >= COLUMN_COUNT) { + return; + } + for (int i = filledColumns; i < COLUMN_COUNT; i++) { + final View spacer = new View(row.getContext()); + spacer.setLayoutParams(new LinearLayout.LayoutParams( + 0, LinearLayout.LayoutParams.WRAP_CONTENT, 1f)); + row.addView(spacer); + } + } + + private static void startEditJiggle(final View avatarStack, final int itemIndex) { + if (avatarStack == null || avatarStack.getWidth() == 0) { + if (avatarStack != null) { + avatarStack.post(() -> startEditJiggle(avatarStack, itemIndex)); + } + return; + } + stopEditJiggle(avatarStack); + avatarStack.setPivotX(avatarStack.getWidth() * 0.5f); + avatarStack.setPivotY(avatarStack.getHeight() * 0.5f); + final float from = (itemIndex & 1) == 0 ? -JIGGLE_DEGREES : JIGGLE_DEGREES; + final float to = (itemIndex & 1) == 0 ? JIGGLE_DEGREES : -JIGGLE_DEGREES; + final ObjectAnimator anim = ObjectAnimator.ofFloat( + avatarStack, View.ROTATION, from, to); + anim.setDuration(150L + (itemIndex % 4) * 18L); + anim.setRepeatCount(ValueAnimator.INFINITE); + anim.setRepeatMode(ValueAnimator.REVERSE); + anim.setInterpolator(new LinearInterpolator()); + anim.setStartDelay((itemIndex % 6) * 40L); + avatarStack.setTag(R.id.tag_home_pinned_jiggle, anim); + anim.start(); + } + + private static void stopEditJiggle(final View avatarStack) { + if (avatarStack == null) { + return; + } + final Object tag = avatarStack.getTag(R.id.tag_home_pinned_jiggle); + if (tag instanceof ObjectAnimator) { + ((ObjectAnimator) tag).cancel(); + } + avatarStack.setTag(R.id.tag_home_pinned_jiggle, null); + avatarStack.setRotation(0f); + } + + private static boolean bindRow(final Cursor cursor, final String conversationId, + final ConversationListItemData out) { + final int saved = cursor.getPosition(); + for (int i = 0; i < cursor.getCount(); i++) { + if (!cursor.moveToPosition(i)) { + continue; + } + out.bind(cursor); + if (conversationId.equals(out.getConversationId())) { + return true; + } + } + if (saved >= 0 && saved < cursor.getCount()) { + cursor.moveToPosition(saved); + } + return false; + } +} diff --git a/app/src/main/java/com/android/messaging/ui/home/PinnedConversationStore.java b/app/src/main/java/com/android/messaging/ui/home/PinnedConversationStore.java new file mode 100644 index 0000000..0bc3421 --- /dev/null +++ b/app/src/main/java/com/android/messaging/ui/home/PinnedConversationStore.java @@ -0,0 +1,130 @@ +/* + * Copyright (C) 2025 The LineageOS Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.messaging.ui.home; + +import android.content.Context; +import android.content.SharedPreferences; +import android.text.TextUtils; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Set; + +/** Persists pinned conversation ids (order preserved, max {@link #MAX_PINS}). */ +public final class PinnedConversationStore { + + public static final int MAX_PINS = 9; + + private static final String PREFS_NAME = "home_pinned_conversations"; + private static final String KEY_ORDER = "pinned_order"; + + private PinnedConversationStore() { + } + + public static boolean isPinned(final Context context, final String conversationId) { + if (TextUtils.isEmpty(conversationId)) { + return false; + } + return getPinnedIds(context).contains(conversationId); + } + + public static List getPinnedIds(final Context context) { + final SharedPreferences prefs = prefs(context); + final Set stored = prefs.getStringSet(KEY_ORDER, null); + if (stored == null || stored.isEmpty()) { + return Collections.emptyList(); + } + final ArrayList ordered = new ArrayList<>(stored.size()); + final String serialized = prefs.getString(KEY_ORDER + "_seq", null); + if (!TextUtils.isEmpty(serialized)) { + final String[] parts = serialized.split(","); + for (final String part : parts) { + if (!TextUtils.isEmpty(part) && stored.contains(part)) { + ordered.add(part); + } + } + } + for (final String id : stored) { + if (!ordered.contains(id)) { + ordered.add(id); + } + } + return ordered; + } + + /** @return true if pinned; false if already pinned or limit reached. */ + public static boolean pin(final Context context, final String conversationId) { + if (TextUtils.isEmpty(conversationId)) { + return false; + } + final List ids = new ArrayList<>(getPinnedIds(context)); + if (ids.contains(conversationId)) { + return true; + } + if (ids.size() >= MAX_PINS) { + return false; + } + ids.add(conversationId); + save(context, ids); + return true; + } + + public static void unpin(final Context context, final String conversationId) { + if (TextUtils.isEmpty(conversationId)) { + return; + } + final List ids = new ArrayList<>(getPinnedIds(context)); + if (ids.remove(conversationId)) { + save(context, ids); + } + } + + public static void pruneMissing(final Context context, final Set validIds) { + final List ids = new ArrayList<>(getPinnedIds(context)); + boolean changed = false; + for (int i = ids.size() - 1; i >= 0; i--) { + if (!validIds.contains(ids.get(i))) { + ids.remove(i); + changed = true; + } + } + if (changed) { + save(context, ids); + } + } + + private static void save(final Context context, final List ids) { + final LinkedHashSet set = new LinkedHashSet<>(ids); + final StringBuilder seq = new StringBuilder(); + for (int i = 0; i < ids.size(); i++) { + if (i > 0) { + seq.append(','); + } + seq.append(ids.get(i)); + } + prefs(context).edit() + .putStringSet(KEY_ORDER, set) + .putString(KEY_ORDER + "_seq", seq.toString()) + .apply(); + } + + private static SharedPreferences prefs(final Context context) { + return context.getApplicationContext().getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE); + } +} diff --git a/src/com/android/messaging/ui/mediapicker/AudioLevelSource.java b/app/src/main/java/com/android/messaging/ui/mediapicker/AudioLevelSource.java similarity index 100% rename from src/com/android/messaging/ui/mediapicker/AudioLevelSource.java rename to app/src/main/java/com/android/messaging/ui/mediapicker/AudioLevelSource.java diff --git a/src/com/android/messaging/ui/mediapicker/AudioMediaChooser.java b/app/src/main/java/com/android/messaging/ui/mediapicker/AudioMediaChooser.java similarity index 100% rename from src/com/android/messaging/ui/mediapicker/AudioMediaChooser.java rename to app/src/main/java/com/android/messaging/ui/mediapicker/AudioMediaChooser.java diff --git a/src/com/android/messaging/ui/mediapicker/AudioRecordView.java b/app/src/main/java/com/android/messaging/ui/mediapicker/AudioRecordView.java similarity index 100% rename from src/com/android/messaging/ui/mediapicker/AudioRecordView.java rename to app/src/main/java/com/android/messaging/ui/mediapicker/AudioRecordView.java diff --git a/src/com/android/messaging/ui/mediapicker/CameraMediaChooser.java b/app/src/main/java/com/android/messaging/ui/mediapicker/CameraMediaChooser.java similarity index 100% rename from src/com/android/messaging/ui/mediapicker/CameraMediaChooser.java rename to app/src/main/java/com/android/messaging/ui/mediapicker/CameraMediaChooser.java diff --git a/src/com/android/messaging/ui/mediapicker/ContactMediaChooser.java b/app/src/main/java/com/android/messaging/ui/mediapicker/ContactMediaChooser.java similarity index 100% rename from src/com/android/messaging/ui/mediapicker/ContactMediaChooser.java rename to app/src/main/java/com/android/messaging/ui/mediapicker/ContactMediaChooser.java diff --git a/src/com/android/messaging/ui/mediapicker/DocumentImagePicker.java b/app/src/main/java/com/android/messaging/ui/mediapicker/DocumentImagePicker.java similarity index 100% rename from src/com/android/messaging/ui/mediapicker/DocumentImagePicker.java rename to app/src/main/java/com/android/messaging/ui/mediapicker/DocumentImagePicker.java diff --git a/src/com/android/messaging/ui/mediapicker/GalleryMediaChooser.java b/app/src/main/java/com/android/messaging/ui/mediapicker/GalleryMediaChooser.java similarity index 100% rename from src/com/android/messaging/ui/mediapicker/GalleryMediaChooser.java rename to app/src/main/java/com/android/messaging/ui/mediapicker/GalleryMediaChooser.java diff --git a/src/com/android/messaging/ui/mediapicker/LevelTrackingMediaRecorder.java b/app/src/main/java/com/android/messaging/ui/mediapicker/LevelTrackingMediaRecorder.java similarity index 100% rename from src/com/android/messaging/ui/mediapicker/LevelTrackingMediaRecorder.java rename to app/src/main/java/com/android/messaging/ui/mediapicker/LevelTrackingMediaRecorder.java diff --git a/src/com/android/messaging/ui/mediapicker/MediaChooser.java b/app/src/main/java/com/android/messaging/ui/mediapicker/MediaChooser.java similarity index 100% rename from src/com/android/messaging/ui/mediapicker/MediaChooser.java rename to app/src/main/java/com/android/messaging/ui/mediapicker/MediaChooser.java diff --git a/src/com/android/messaging/ui/mediapicker/MediaPicker.java b/app/src/main/java/com/android/messaging/ui/mediapicker/MediaPicker.java similarity index 100% rename from src/com/android/messaging/ui/mediapicker/MediaPicker.java rename to app/src/main/java/com/android/messaging/ui/mediapicker/MediaPicker.java diff --git a/src/com/android/messaging/ui/mediapicker/MediaPickerGridView.java b/app/src/main/java/com/android/messaging/ui/mediapicker/MediaPickerGridView.java similarity index 100% rename from src/com/android/messaging/ui/mediapicker/MediaPickerGridView.java rename to app/src/main/java/com/android/messaging/ui/mediapicker/MediaPickerGridView.java diff --git a/src/com/android/messaging/ui/mediapicker/MediaPickerPanel.java b/app/src/main/java/com/android/messaging/ui/mediapicker/MediaPickerPanel.java similarity index 100% rename from src/com/android/messaging/ui/mediapicker/MediaPickerPanel.java rename to app/src/main/java/com/android/messaging/ui/mediapicker/MediaPickerPanel.java diff --git a/src/com/android/messaging/ui/mediapicker/PausableChronometer.java b/app/src/main/java/com/android/messaging/ui/mediapicker/PausableChronometer.java similarity index 100% rename from src/com/android/messaging/ui/mediapicker/PausableChronometer.java rename to app/src/main/java/com/android/messaging/ui/mediapicker/PausableChronometer.java diff --git a/src/com/android/messaging/ui/mediapicker/SoundLevels.java b/app/src/main/java/com/android/messaging/ui/mediapicker/SoundLevels.java similarity index 100% rename from src/com/android/messaging/ui/mediapicker/SoundLevels.java rename to app/src/main/java/com/android/messaging/ui/mediapicker/SoundLevels.java diff --git a/src/com/android/messaging/ui/photoviewer/BuglePhotoBitmapLoader.java b/app/src/main/java/com/android/messaging/ui/photoviewer/BuglePhotoBitmapLoader.java similarity index 100% rename from src/com/android/messaging/ui/photoviewer/BuglePhotoBitmapLoader.java rename to app/src/main/java/com/android/messaging/ui/photoviewer/BuglePhotoBitmapLoader.java diff --git a/src/com/android/messaging/ui/photoviewer/BuglePhotoPageAdapter.java b/app/src/main/java/com/android/messaging/ui/photoviewer/BuglePhotoPageAdapter.java similarity index 100% rename from src/com/android/messaging/ui/photoviewer/BuglePhotoPageAdapter.java rename to app/src/main/java/com/android/messaging/ui/photoviewer/BuglePhotoPageAdapter.java diff --git a/src/com/android/messaging/ui/photoviewer/BuglePhotoViewActivity.java b/app/src/main/java/com/android/messaging/ui/photoviewer/BuglePhotoViewActivity.java similarity index 100% rename from src/com/android/messaging/ui/photoviewer/BuglePhotoViewActivity.java rename to app/src/main/java/com/android/messaging/ui/photoviewer/BuglePhotoViewActivity.java diff --git a/src/com/android/messaging/ui/photoviewer/BuglePhotoViewController.java b/app/src/main/java/com/android/messaging/ui/photoviewer/BuglePhotoViewController.java similarity index 100% rename from src/com/android/messaging/ui/photoviewer/BuglePhotoViewController.java rename to app/src/main/java/com/android/messaging/ui/photoviewer/BuglePhotoViewController.java diff --git a/src/com/android/messaging/ui/photoviewer/BuglePhotoViewFragment.java b/app/src/main/java/com/android/messaging/ui/photoviewer/BuglePhotoViewFragment.java similarity index 100% rename from src/com/android/messaging/ui/photoviewer/BuglePhotoViewFragment.java rename to app/src/main/java/com/android/messaging/ui/photoviewer/BuglePhotoViewFragment.java diff --git a/src/com/android/messaging/util/AccessibilityUtil.java b/app/src/main/java/com/android/messaging/util/AccessibilityUtil.java similarity index 100% rename from src/com/android/messaging/util/AccessibilityUtil.java rename to app/src/main/java/com/android/messaging/util/AccessibilityUtil.java diff --git a/src/com/android/messaging/util/Assert.java b/app/src/main/java/com/android/messaging/util/Assert.java similarity index 100% rename from src/com/android/messaging/util/Assert.java rename to app/src/main/java/com/android/messaging/util/Assert.java diff --git a/src/com/android/messaging/util/AvatarUriUtil.java b/app/src/main/java/com/android/messaging/util/AvatarUriUtil.java similarity index 100% rename from src/com/android/messaging/util/AvatarUriUtil.java rename to app/src/main/java/com/android/messaging/util/AvatarUriUtil.java diff --git a/src/com/android/messaging/util/BugleActivityUtil.java b/app/src/main/java/com/android/messaging/util/BugleActivityUtil.java similarity index 100% rename from src/com/android/messaging/util/BugleActivityUtil.java rename to app/src/main/java/com/android/messaging/util/BugleActivityUtil.java diff --git a/src/com/android/messaging/util/BugleApplicationPrefs.java b/app/src/main/java/com/android/messaging/util/BugleApplicationPrefs.java similarity index 100% rename from src/com/android/messaging/util/BugleApplicationPrefs.java rename to app/src/main/java/com/android/messaging/util/BugleApplicationPrefs.java diff --git a/src/com/android/messaging/util/BugleGservicesKeys.java b/app/src/main/java/com/android/messaging/util/BugleGservicesKeys.java similarity index 100% rename from src/com/android/messaging/util/BugleGservicesKeys.java rename to app/src/main/java/com/android/messaging/util/BugleGservicesKeys.java diff --git a/src/com/android/messaging/util/BuglePrefs.java b/app/src/main/java/com/android/messaging/util/BuglePrefs.java similarity index 100% rename from src/com/android/messaging/util/BuglePrefs.java rename to app/src/main/java/com/android/messaging/util/BuglePrefs.java diff --git a/src/com/android/messaging/util/BuglePrefsImpl.java b/app/src/main/java/com/android/messaging/util/BuglePrefsImpl.java similarity index 100% rename from src/com/android/messaging/util/BuglePrefsImpl.java rename to app/src/main/java/com/android/messaging/util/BuglePrefsImpl.java diff --git a/src/com/android/messaging/util/BuglePrefsKeys.java b/app/src/main/java/com/android/messaging/util/BuglePrefsKeys.java similarity index 100% rename from src/com/android/messaging/util/BuglePrefsKeys.java rename to app/src/main/java/com/android/messaging/util/BuglePrefsKeys.java diff --git a/src/com/android/messaging/util/BugleSubscriptionPrefs.java b/app/src/main/java/com/android/messaging/util/BugleSubscriptionPrefs.java similarity index 100% rename from src/com/android/messaging/util/BugleSubscriptionPrefs.java rename to app/src/main/java/com/android/messaging/util/BugleSubscriptionPrefs.java diff --git a/src/com/android/messaging/util/BugleWidgetPrefs.java b/app/src/main/java/com/android/messaging/util/BugleWidgetPrefs.java similarity index 100% rename from src/com/android/messaging/util/BugleWidgetPrefs.java rename to app/src/main/java/com/android/messaging/util/BugleWidgetPrefs.java diff --git a/src/com/android/messaging/util/ChangeDefaultSmsAppHelper.java b/app/src/main/java/com/android/messaging/util/ChangeDefaultSmsAppHelper.java similarity index 100% rename from src/com/android/messaging/util/ChangeDefaultSmsAppHelper.java rename to app/src/main/java/com/android/messaging/util/ChangeDefaultSmsAppHelper.java diff --git a/src/com/android/messaging/util/ConnectivityUtil.java b/app/src/main/java/com/android/messaging/util/ConnectivityUtil.java similarity index 100% rename from src/com/android/messaging/util/ConnectivityUtil.java rename to app/src/main/java/com/android/messaging/util/ConnectivityUtil.java diff --git a/src/com/android/messaging/util/ContactRecipientEntryUtils.java b/app/src/main/java/com/android/messaging/util/ContactRecipientEntryUtils.java similarity index 100% rename from src/com/android/messaging/util/ContactRecipientEntryUtils.java rename to app/src/main/java/com/android/messaging/util/ContactRecipientEntryUtils.java diff --git a/src/com/android/messaging/util/ContactUtil.java b/app/src/main/java/com/android/messaging/util/ContactUtil.java similarity index 100% rename from src/com/android/messaging/util/ContactUtil.java rename to app/src/main/java/com/android/messaging/util/ContactUtil.java diff --git a/src/com/android/messaging/util/ConversationIdSet.java b/app/src/main/java/com/android/messaging/util/ConversationIdSet.java similarity index 100% rename from src/com/android/messaging/util/ConversationIdSet.java rename to app/src/main/java/com/android/messaging/util/ConversationIdSet.java diff --git a/src/com/android/messaging/util/CubicBezierInterpolator.java b/app/src/main/java/com/android/messaging/util/CubicBezierInterpolator.java similarity index 100% rename from src/com/android/messaging/util/CubicBezierInterpolator.java rename to app/src/main/java/com/android/messaging/util/CubicBezierInterpolator.java diff --git a/src/com/android/messaging/util/Dates.java b/app/src/main/java/com/android/messaging/util/Dates.java similarity index 100% rename from src/com/android/messaging/util/Dates.java rename to app/src/main/java/com/android/messaging/util/Dates.java diff --git a/src/com/android/messaging/util/DebugUtils.java b/app/src/main/java/com/android/messaging/util/DebugUtils.java similarity index 100% rename from src/com/android/messaging/util/DebugUtils.java rename to app/src/main/java/com/android/messaging/util/DebugUtils.java diff --git a/src/com/android/messaging/util/EmailAddress.java b/app/src/main/java/com/android/messaging/util/EmailAddress.java similarity index 100% rename from src/com/android/messaging/util/EmailAddress.java rename to app/src/main/java/com/android/messaging/util/EmailAddress.java diff --git a/src/com/android/messaging/util/FallbackStrategies.java b/app/src/main/java/com/android/messaging/util/FallbackStrategies.java similarity index 100% rename from src/com/android/messaging/util/FallbackStrategies.java rename to app/src/main/java/com/android/messaging/util/FallbackStrategies.java diff --git a/src/com/android/messaging/util/FileUtil.java b/app/src/main/java/com/android/messaging/util/FileUtil.java similarity index 100% rename from src/com/android/messaging/util/FileUtil.java rename to app/src/main/java/com/android/messaging/util/FileUtil.java diff --git a/src/com/android/messaging/util/GifTranscoder.java b/app/src/main/java/com/android/messaging/util/GifTranscoder.java similarity index 88% rename from src/com/android/messaging/util/GifTranscoder.java rename to app/src/main/java/com/android/messaging/util/GifTranscoder.java index 168da5f..9fca6fd 100644 --- a/src/com/android/messaging/util/GifTranscoder.java +++ b/app/src/main/java/com/android/messaging/util/GifTranscoder.java @@ -38,11 +38,22 @@ public class GifTranscoder { private static final int MIN_HEIGHT = 100; private static final int MIN_WIDTH = 100; + private static final boolean sNativeLoaded; static { - System.loadLibrary("giftranscode"); + boolean loaded = false; + try { + System.loadLibrary("giftranscode"); + loaded = true; + } catch (UnsatisfiedLinkError e) { + // Native lib optional in standalone Gradle builds. + } + sNativeLoaded = loaded; } public static boolean transcode(Context context, String filePath, String outFilePath) { + if (!sNativeLoaded) { + return false; + } final long inputSize = new File(filePath).length(); Stopwatch stopwatch = Stopwatch.createStarted(); final boolean success = transcodeInternal(filePath, outFilePath); diff --git a/src/com/android/messaging/util/ImageUtils.java b/app/src/main/java/com/android/messaging/util/ImageUtils.java similarity index 100% rename from src/com/android/messaging/util/ImageUtils.java rename to app/src/main/java/com/android/messaging/util/ImageUtils.java diff --git a/src/com/android/messaging/util/ImeUtil.java b/app/src/main/java/com/android/messaging/util/ImeUtil.java similarity index 100% rename from src/com/android/messaging/util/ImeUtil.java rename to app/src/main/java/com/android/messaging/util/ImeUtil.java diff --git a/src/com/android/messaging/util/LinkifyHelper.java b/app/src/main/java/com/android/messaging/util/LinkifyHelper.java similarity index 100% rename from src/com/android/messaging/util/LinkifyHelper.java rename to app/src/main/java/com/android/messaging/util/LinkifyHelper.java diff --git a/src/com/android/messaging/util/LogUtil.java b/app/src/main/java/com/android/messaging/util/LogUtil.java similarity index 100% rename from src/com/android/messaging/util/LogUtil.java rename to app/src/main/java/com/android/messaging/util/LogUtil.java diff --git a/src/com/android/messaging/util/LoggingTimer.java b/app/src/main/java/com/android/messaging/util/LoggingTimer.java similarity index 100% rename from src/com/android/messaging/util/LoggingTimer.java rename to app/src/main/java/com/android/messaging/util/LoggingTimer.java diff --git a/src/com/android/messaging/util/MediaMetadataRetrieverWrapper.java b/app/src/main/java/com/android/messaging/util/MediaMetadataRetrieverWrapper.java similarity index 100% rename from src/com/android/messaging/util/MediaMetadataRetrieverWrapper.java rename to app/src/main/java/com/android/messaging/util/MediaMetadataRetrieverWrapper.java diff --git a/src/com/android/messaging/util/MediaUtil.java b/app/src/main/java/com/android/messaging/util/MediaUtil.java similarity index 100% rename from src/com/android/messaging/util/MediaUtil.java rename to app/src/main/java/com/android/messaging/util/MediaUtil.java diff --git a/src/com/android/messaging/util/MediaUtilImpl.java b/app/src/main/java/com/android/messaging/util/MediaUtilImpl.java similarity index 100% rename from src/com/android/messaging/util/MediaUtilImpl.java rename to app/src/main/java/com/android/messaging/util/MediaUtilImpl.java diff --git a/src/com/android/messaging/util/NotificationPlayer.java b/app/src/main/java/com/android/messaging/util/NotificationPlayer.java similarity index 100% rename from src/com/android/messaging/util/NotificationPlayer.java rename to app/src/main/java/com/android/messaging/util/NotificationPlayer.java diff --git a/src/com/android/messaging/util/NotificationsUtil.java b/app/src/main/java/com/android/messaging/util/NotificationsUtil.java similarity index 100% rename from src/com/android/messaging/util/NotificationsUtil.java rename to app/src/main/java/com/android/messaging/util/NotificationsUtil.java diff --git a/src/com/android/messaging/util/OsUtil.java b/app/src/main/java/com/android/messaging/util/OsUtil.java similarity index 100% rename from src/com/android/messaging/util/OsUtil.java rename to app/src/main/java/com/android/messaging/util/OsUtil.java diff --git a/src/com/android/messaging/util/PendingIntentConstants.java b/app/src/main/java/com/android/messaging/util/PendingIntentConstants.java similarity index 100% rename from src/com/android/messaging/util/PendingIntentConstants.java rename to app/src/main/java/com/android/messaging/util/PendingIntentConstants.java diff --git a/src/com/android/messaging/util/PhoneUtils.java b/app/src/main/java/com/android/messaging/util/PhoneUtils.java similarity index 100% rename from src/com/android/messaging/util/PhoneUtils.java rename to app/src/main/java/com/android/messaging/util/PhoneUtils.java diff --git a/src/com/android/messaging/util/TextUtil.java b/app/src/main/java/com/android/messaging/util/TextUtil.java similarity index 100% rename from src/com/android/messaging/util/TextUtil.java rename to app/src/main/java/com/android/messaging/util/TextUtil.java diff --git a/src/com/android/messaging/util/ThreadUtil.java b/app/src/main/java/com/android/messaging/util/ThreadUtil.java similarity index 100% rename from src/com/android/messaging/util/ThreadUtil.java rename to app/src/main/java/com/android/messaging/util/ThreadUtil.java diff --git a/src/com/android/messaging/util/Trace.java b/app/src/main/java/com/android/messaging/util/Trace.java similarity index 100% rename from src/com/android/messaging/util/Trace.java rename to app/src/main/java/com/android/messaging/util/Trace.java diff --git a/src/com/android/messaging/util/Typefaces.java b/app/src/main/java/com/android/messaging/util/Typefaces.java similarity index 100% rename from src/com/android/messaging/util/Typefaces.java rename to app/src/main/java/com/android/messaging/util/Typefaces.java diff --git a/src/com/android/messaging/util/UiUtils.java b/app/src/main/java/com/android/messaging/util/UiUtils.java similarity index 100% rename from src/com/android/messaging/util/UiUtils.java rename to app/src/main/java/com/android/messaging/util/UiUtils.java diff --git a/src/com/android/messaging/util/UriUtil.java b/app/src/main/java/com/android/messaging/util/UriUtil.java similarity index 100% rename from src/com/android/messaging/util/UriUtil.java rename to app/src/main/java/com/android/messaging/util/UriUtil.java diff --git a/src/com/android/messaging/util/VersionUtil.java b/app/src/main/java/com/android/messaging/util/VersionUtil.java similarity index 100% rename from src/com/android/messaging/util/VersionUtil.java rename to app/src/main/java/com/android/messaging/util/VersionUtil.java diff --git a/src/com/android/messaging/util/YouTubeUtil.java b/app/src/main/java/com/android/messaging/util/YouTubeUtil.java similarity index 100% rename from src/com/android/messaging/util/YouTubeUtil.java rename to app/src/main/java/com/android/messaging/util/YouTubeUtil.java diff --git a/src/com/android/messaging/util/exif/ExifInterface.java b/app/src/main/java/com/android/messaging/util/exif/ExifInterface.java similarity index 100% rename from src/com/android/messaging/util/exif/ExifInterface.java rename to app/src/main/java/com/android/messaging/util/exif/ExifInterface.java diff --git a/src/com/android/messaging/widget/BaseWidgetFactory.java b/app/src/main/java/com/android/messaging/widget/BaseWidgetFactory.java similarity index 100% rename from src/com/android/messaging/widget/BaseWidgetFactory.java rename to app/src/main/java/com/android/messaging/widget/BaseWidgetFactory.java diff --git a/src/com/android/messaging/widget/BaseWidgetProvider.java b/app/src/main/java/com/android/messaging/widget/BaseWidgetProvider.java similarity index 100% rename from src/com/android/messaging/widget/BaseWidgetProvider.java rename to app/src/main/java/com/android/messaging/widget/BaseWidgetProvider.java diff --git a/src/com/android/messaging/widget/BugleWidgetProvider.java b/app/src/main/java/com/android/messaging/widget/BugleWidgetProvider.java similarity index 100% rename from src/com/android/messaging/widget/BugleWidgetProvider.java rename to app/src/main/java/com/android/messaging/widget/BugleWidgetProvider.java diff --git a/src/com/android/messaging/widget/WidgetConversationListService.java b/app/src/main/java/com/android/messaging/widget/WidgetConversationListService.java similarity index 100% rename from src/com/android/messaging/widget/WidgetConversationListService.java rename to app/src/main/java/com/android/messaging/widget/WidgetConversationListService.java diff --git a/src/com/android/messaging/widget/WidgetConversationProvider.java b/app/src/main/java/com/android/messaging/widget/WidgetConversationProvider.java similarity index 100% rename from src/com/android/messaging/widget/WidgetConversationProvider.java rename to app/src/main/java/com/android/messaging/widget/WidgetConversationProvider.java diff --git a/src/com/android/messaging/widget/WidgetConversationService.java b/app/src/main/java/com/android/messaging/widget/WidgetConversationService.java similarity index 100% rename from src/com/android/messaging/widget/WidgetConversationService.java rename to app/src/main/java/com/android/messaging/widget/WidgetConversationService.java diff --git a/src/org/lineageos/messaging/util/PrefsUtils.java b/app/src/main/java/org/lineageos/messaging/util/PrefsUtils.java similarity index 100% rename from src/org/lineageos/messaging/util/PrefsUtils.java rename to app/src/main/java/org/lineageos/messaging/util/PrefsUtils.java diff --git a/app/src/main/jni/Android.bp b/app/src/main/jni/Android.bp new file mode 100644 index 0000000..22840ea --- /dev/null +++ b/app/src/main/jni/Android.bp @@ -0,0 +1,40 @@ +// Copyright (C) 2015 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package { + // See: http://go/android-license-faq + default_applicable_licenses: ["Android-Apache-2.0"], +} + +cc_library_shared { + name: "libgiftranscode", + static_libs: ["libgif"], + // Link to Android logging (liblog.so) and dynamic linker (libdl.so) libraries + shared_libs: [ + "liblog", + "libdl", + ], + // for including the jni.h file + header_libs: ["jni_headers"], + include_dirs: ["external/giflib"], + srcs: ["GifTranscoder.cpp"], + cflags: [ + "-Wno-unused-parameter", + "-Wno-switch", + ], + sdk_version: "19", + // LLVM libc++ + stl: "c++_static", + product_specific: true, +} diff --git a/app/src/main/jni/GifTranscoder.cpp b/app/src/main/jni/GifTranscoder.cpp new file mode 100644 index 0000000..324d315 --- /dev/null +++ b/app/src/main/jni/GifTranscoder.cpp @@ -0,0 +1,583 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include + +#include + +#include "GifTranscoder.h" + +#define SQUARE(a) ((a)*(a)) + +// GIF does not support partial transparency, so our alpha channels are always 0x0 or 0xff. +static const ColorARGB TRANSPARENT = 0x0; + +#define ALPHA(color) (((color) >> 24) & 0xff) +#define RED(color) (((color) >> 16) & 0xff) +#define GREEN(color) (((color) >> 8) & 0xff) +#define BLUE(color) (((color) >> 0) & 0xff) + +#define MAKE_COLOR_ARGB(a, r, g, b) \ + ((a) << 24 | (r) << 16 | (g) << 8 | (b)) + +#define MAX_COLOR_DISTANCE (255 * 255 * 255) + +#define TAG "GifTranscoder.cpp" +#define LOGD_ENABLED 0 +#if LOGD_ENABLED +#define LOGD(...) ((void)__android_log_print(ANDROID_LOG_DEBUG, TAG, __VA_ARGS__)) +#else +#define LOGD(...) ((void)0) +#endif +#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, TAG, __VA_ARGS__)) +#define LOGW(...) ((void)__android_log_print(ANDROID_LOG_WARN, TAG, __VA_ARGS__)) +#define LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR, TAG, __VA_ARGS__)) + +// This macro expects the assertion to pass, but logs a FATAL if not. +#define ASSERT(cond, ...) \ + ( (__builtin_expect((cond) == 0, 0)) \ + ? ((void)__android_log_assert(#cond, TAG, ## __VA_ARGS__)) \ + : (void) 0 ) +#define ASSERT_ENABLED 1 + +namespace { + +// Current time in milliseconds since Unix epoch. +double now(void) { + struct timespec res; + clock_gettime(CLOCK_REALTIME, &res); + return 1000.0 * res.tv_sec + (double) res.tv_nsec / 1e6; +} + +// Gets the pixel at position (x,y) from a buffer that uses row-major order to store an image with +// the specified width. +template +T* getPixel(T* buffer, int width, int x, int y) { + return buffer + (y * width + x); +} + +} // namespace + +int GifTranscoder::transcode(const char* pathIn, const char* pathOut) { + int error; + double t0; + GifFileType* gifIn; + GifFileType* gifOut; + + // Automatically closes the GIF files when this method returns + GifFilesCloser closer; + + gifIn = DGifOpenFileName(pathIn, &error); + if (gifIn) { + closer.setGifIn(gifIn); + LOGD("Opened input GIF: %s", pathIn); + } else { + LOGE("Could not open input GIF: %s, error = %d", pathIn, error); + return GIF_ERROR; + } + + gifOut = EGifOpenFileName(pathOut, false, &error); + if (gifOut) { + closer.setGifOut(gifOut); + LOGD("Opened output GIF: %s", pathOut); + } else { + LOGE("Could not open output GIF: %s, error = %d", pathOut, error); + return GIF_ERROR; + } + + t0 = now(); + if (resizeBoxFilter(gifIn, gifOut)) { + LOGD("Resized GIF in %.2f ms", now() - t0); + } else { + LOGE("Could not resize GIF"); + return GIF_ERROR; + } + + return GIF_OK; +} + +bool GifTranscoder::resizeBoxFilter(GifFileType* gifIn, GifFileType* gifOut) { + ASSERT(gifIn != NULL, "gifIn cannot be NULL"); + ASSERT(gifOut != NULL, "gifOut cannot be NULL"); + + if (gifIn->SWidth < 0 || gifIn->SHeight < 0) { + LOGE("Input GIF has invalid size: %d x %d", gifIn->SWidth, gifIn->SHeight); + return false; + } + + // Output GIF will be 50% the size of the original. + if (EGifPutScreenDesc(gifOut, + gifIn->SWidth / 2, + gifIn->SHeight / 2, + gifIn->SColorResolution, + gifIn->SBackGroundColor, + gifIn->SColorMap) == GIF_ERROR) { + LOGE("Could not write screen descriptor"); + return false; + } + LOGD("Wrote screen descriptor"); + + // Index of the current image. + int imageIndex = 0; + + // Transparent color of the current image. + int transparentColor = NO_TRANSPARENT_COLOR; + + // Buffer for reading raw images from the input GIF. + std::vector srcBuffer(gifIn->SWidth * gifIn->SHeight); + + // Buffer for rendering images from the input GIF. + std::unique_ptr renderBuffer(new ColorARGB[gifIn->SWidth * gifIn->SHeight]); + + // Buffer for writing new images to output GIF (one row at a time). + std::unique_ptr dstRowBuffer(new GifByteType[gifOut->SWidth]); + + // Many GIFs use DISPOSE_DO_NOT to make images draw on top of previous images. They can also + // use DISPOSE_BACKGROUND to clear the last image region before drawing the next one. We need + // to keep track of the disposal mode as we go along to properly render the GIF. + int disposalMode = DISPOSAL_UNSPECIFIED; + int prevImageDisposalMode = DISPOSAL_UNSPECIFIED; + GifImageDesc prevImageDimens; + + // Background color (applies to entire GIF). + ColorARGB bgColor = TRANSPARENT; + + GifRecordType recordType; + do { + if (DGifGetRecordType(gifIn, &recordType) == GIF_ERROR) { + LOGE("Could not get record type"); + return false; + } + LOGD("Read record type: %d", recordType); + switch (recordType) { + case IMAGE_DESC_RECORD_TYPE: { + if (DGifGetImageDesc(gifIn) == GIF_ERROR) { + LOGE("Could not read image descriptor (%d)", imageIndex); + return false; + } + + // Check the current image position. + if (gifIn->Image.Left < 0 || + gifIn->Image.Top < 0 || + gifIn->Image.Left + gifIn->Image.Width > gifIn->SWidth || + gifIn->Image.Top + gifIn->Image.Height > gifIn->SHeight) { + LOGE("GIF image extends beyond logical screen"); + return false; + } + + // Write the new image descriptor. + if (EGifPutImageDesc(gifOut, + 0, // Left + 0, // Top + gifOut->SWidth, + gifOut->SHeight, + false, // Interlace + gifIn->Image.ColorMap) == GIF_ERROR) { + LOGE("Could not write image descriptor (%d)", imageIndex); + return false; + } + + // Read the image from the input GIF. The buffer is already initialized to the + // size of the GIF, which is usually equal to the size of all the images inside it. + // If not, the call to resize below ensures that the buffer is the right size. + srcBuffer.resize(gifIn->Image.Width * gifIn->Image.Height); + if (readImage(gifIn, srcBuffer.data()) == false) { + LOGE("Could not read image data (%d)", imageIndex); + return false; + } + LOGD("Read image data (%d)", imageIndex); + // Render the image from the input GIF. + if (renderImage(gifIn, + srcBuffer.data(), + imageIndex, + transparentColor, + renderBuffer.get(), + bgColor, + prevImageDimens, + prevImageDisposalMode) == false) { + LOGE("Could not render %d", imageIndex); + return false; + } + LOGD("Rendered image (%d)", imageIndex); + + // Generate the image in the output GIF. + for (int y = 0; y < gifOut->SHeight; y++) { + for (int x = 0; x < gifOut->SWidth; x++) { + const GifByteType dstColorIndex = computeNewColorIndex( + gifIn, transparentColor, renderBuffer.get(), x, y); + *(dstRowBuffer.get() + x) = dstColorIndex; + } + if (EGifPutLine(gifOut, dstRowBuffer.get(), gifOut->SWidth) == GIF_ERROR) { + LOGE("Could not write raster data (%d)", imageIndex); + return false; + } + } + LOGD("Wrote raster data (%d)", imageIndex); + + // Save the disposal mode for rendering the next image. + // We only support DISPOSE_DO_NOT and DISPOSE_BACKGROUND. + prevImageDisposalMode = disposalMode; + if (prevImageDisposalMode == DISPOSAL_UNSPECIFIED) { + prevImageDisposalMode = DISPOSE_DO_NOT; + } else if (prevImageDisposalMode == DISPOSE_PREVIOUS) { + prevImageDisposalMode = DISPOSE_BACKGROUND; + } + if (prevImageDisposalMode == DISPOSE_BACKGROUND) { + prevImageDimens.Left = gifIn->Image.Left; + prevImageDimens.Top = gifIn->Image.Top; + prevImageDimens.Width = gifIn->Image.Width; + prevImageDimens.Height = gifIn->Image.Height; + } + + if (gifOut->Image.ColorMap) { + GifFreeMapObject(gifOut->Image.ColorMap); + gifOut->Image.ColorMap = NULL; + } + + imageIndex++; + } break; + case EXTENSION_RECORD_TYPE: { + int extCode; + GifByteType* ext; + if (DGifGetExtension(gifIn, &extCode, &ext) == GIF_ERROR) { + LOGE("Could not read extension block"); + return false; + } + LOGD("Read extension block, code: %d", extCode); + if (extCode == GRAPHICS_EXT_FUNC_CODE) { + GraphicsControlBlock gcb; + if (DGifExtensionToGCB(ext[0], ext + 1, &gcb) == GIF_ERROR) { + LOGE("Could not interpret GCB extension"); + return false; + } + transparentColor = gcb.TransparentColor; + + // This logic for setting the background color based on the first GCB + // doesn't quite match the GIF spec, but empirically it seems to work and it + // matches what libframesequence (Rastermill) does. + if (imageIndex == 0 && gifIn->SColorMap) { + if (gcb.TransparentColor == NO_TRANSPARENT_COLOR) { + if (gifIn->SBackGroundColor < 0 || + gifIn->SBackGroundColor >= gifIn->SColorMap->ColorCount) { + LOGE("SBackGroundColor overflow"); + return false; + } + GifColorType bgColorIndex = + gifIn->SColorMap->Colors[gifIn->SBackGroundColor]; + bgColor = gifColorToColorARGB(bgColorIndex); + LOGD("Set background color based on first GCB"); + } + } + + // Record the original disposal mode and then update it. + disposalMode = gcb.DisposalMode; + gcb.DisposalMode = DISPOSE_BACKGROUND; + EGifGCBToExtension(&gcb, ext + 1); + } + if (EGifPutExtensionLeader(gifOut, extCode) == GIF_ERROR) { + LOGE("Could not write extension leader"); + return false; + } + if (EGifPutExtensionBlock(gifOut, ext[0], ext + 1) == GIF_ERROR) { + LOGE("Could not write extension block"); + return false; + } + LOGD("Wrote extension block"); + while (ext != NULL) { + if (DGifGetExtensionNext(gifIn, &ext) == GIF_ERROR) { + LOGE("Could not read extension continuation"); + return false; + } + if (ext != NULL) { + LOGD("Read extension continuation"); + if (EGifPutExtensionBlock(gifOut, ext[0], ext + 1) == GIF_ERROR) { + LOGE("Could not write extension continuation"); + return false; + } + LOGD("Wrote extension continuation"); + } + } + if (EGifPutExtensionTrailer(gifOut) == GIF_ERROR) { + LOGE("Could not write extension trailer"); + return false; + } + } break; + } + + } while (recordType != TERMINATE_RECORD_TYPE); + LOGD("No more records"); + + return true; +} + +bool GifTranscoder::readImage(GifFileType* gifIn, GifByteType* rasterBits) { + if (gifIn->Image.Interlace) { + int interlacedOffset[] = { 0, 4, 2, 1 }; + int interlacedJumps[] = { 8, 8, 4, 2 }; + + // Need to perform 4 passes on the image + for (int i = 0; i < 4; i++) { + for (int j = interlacedOffset[i]; j < gifIn->Image.Height; j += interlacedJumps[i]) { + if (DGifGetLine(gifIn, + rasterBits + j * gifIn->Image.Width, + gifIn->Image.Width) == GIF_ERROR) { + LOGE("Could not read interlaced raster data"); + return false; + } + } + } + } else { + if (DGifGetLine(gifIn, rasterBits, gifIn->Image.Width * gifIn->Image.Height) == GIF_ERROR) { + LOGE("Could not read raster data"); + return false; + } + } + return true; +} + +bool GifTranscoder::renderImage(GifFileType* gifIn, + GifByteType* rasterBits, + int imageIndex, + int transparentColorIndex, + ColorARGB* renderBuffer, + ColorARGB bgColor, + GifImageDesc prevImageDimens, + int prevImageDisposalMode) { + ASSERT(imageIndex < gifIn->ImageCount, + "Image index %d is out of bounds (count=%d)", imageIndex, gifIn->ImageCount); + + ColorMapObject* colorMap = getColorMap(gifIn); + if (colorMap == NULL) { + LOGE("No GIF color map found"); + return false; + } + + // Clear all or part of the background, before drawing the first image and maybe before drawing + // subsequent images (depending on the DisposalMode). + if (imageIndex == 0) { + fillRect(renderBuffer, gifIn->SWidth, gifIn->SHeight, + 0, 0, gifIn->SWidth, gifIn->SHeight, bgColor); + } else if (prevImageDisposalMode == DISPOSE_BACKGROUND) { + fillRect(renderBuffer, gifIn->SWidth, gifIn->SHeight, + prevImageDimens.Left, prevImageDimens.Top, + prevImageDimens.Width, prevImageDimens.Height, TRANSPARENT); + } + + // Paint this image onto the canvas + for (int y = 0; y < gifIn->Image.Height; y++) { + for (int x = 0; x < gifIn->Image.Width; x++) { + GifByteType colorIndex = *getPixel(rasterBits, gifIn->Image.Width, x, y); + if (colorIndex >= colorMap->ColorCount) { + LOGE("Color Index %d is out of bounds (count=%d)", colorIndex, + colorMap->ColorCount); + return false; + } + + // This image may be smaller than the GIF's "logical screen" + int renderX = x + gifIn->Image.Left; + int renderY = y + gifIn->Image.Top; + + // Skip drawing transparent pixels if this image renders on top of the last one + if (imageIndex > 0 && prevImageDisposalMode == DISPOSE_DO_NOT && + colorIndex == transparentColorIndex) { + continue; + } + + ColorARGB* renderPixel = getPixel(renderBuffer, gifIn->SWidth, renderX, renderY); + *renderPixel = getColorARGB(colorMap, transparentColorIndex, colorIndex); + } + } + return true; +} + +void GifTranscoder::fillRect(ColorARGB* renderBuffer, + int imageWidth, + int imageHeight, + int left, + int top, + int width, + int height, + ColorARGB color) { + ASSERT(left + width <= imageWidth, "Rectangle is outside image bounds"); + ASSERT(top + height <= imageHeight, "Rectangle is outside image bounds"); + + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + ColorARGB* renderPixel = getPixel(renderBuffer, imageWidth, x + left, y + top); + *renderPixel = color; + } + } +} + +GifByteType GifTranscoder::computeNewColorIndex(GifFileType* gifIn, + int transparentColorIndex, + ColorARGB* renderBuffer, + int x, + int y) { + ColorMapObject* colorMap = getColorMap(gifIn); + + // Compute the average color of 4 adjacent pixels from the input image. + ColorARGB c1 = *getPixel(renderBuffer, gifIn->SWidth, x * 2, y * 2); + ColorARGB c2 = *getPixel(renderBuffer, gifIn->SWidth, x * 2 + 1, y * 2); + ColorARGB c3 = *getPixel(renderBuffer, gifIn->SWidth, x * 2, y * 2 + 1); + ColorARGB c4 = *getPixel(renderBuffer, gifIn->SWidth, x * 2 + 1, y * 2 + 1); + ColorARGB avgColor = computeAverage(c1, c2, c3, c4); + + // Search the color map for the best match. + return findBestColor(colorMap, transparentColorIndex, avgColor); +} + +ColorARGB GifTranscoder::computeAverage(ColorARGB c1, ColorARGB c2, ColorARGB c3, ColorARGB c4) { + char avgAlpha = (char)(((int) ALPHA(c1) + (int) ALPHA(c2) + + (int) ALPHA(c3) + (int) ALPHA(c4)) / 4); + char avgRed = (char)(((int) RED(c1) + (int) RED(c2) + + (int) RED(c3) + (int) RED(c4)) / 4); + char avgGreen = (char)(((int) GREEN(c1) + (int) GREEN(c2) + + (int) GREEN(c3) + (int) GREEN(c4)) / 4); + char avgBlue = (char)(((int) BLUE(c1) + (int) BLUE(c2) + + (int) BLUE(c3) + (int) BLUE(c4)) / 4); + return MAKE_COLOR_ARGB(avgAlpha, avgRed, avgGreen, avgBlue); +} + +GifByteType GifTranscoder::findBestColor(ColorMapObject* colorMap, int transparentColorIndex, + ColorARGB targetColor) { + // Return the transparent color if the average alpha is zero. + char alpha = ALPHA(targetColor); + if (alpha == 0 && transparentColorIndex != NO_TRANSPARENT_COLOR) { + return transparentColorIndex; + } + + GifByteType closestColorIndex = 0; + int closestColorDistance = MAX_COLOR_DISTANCE; + for (int i = 0; i < colorMap->ColorCount; i++) { + // Skip the transparent color (we've already eliminated that option). + if (i == transparentColorIndex) { + continue; + } + ColorARGB indexedColor = gifColorToColorARGB(colorMap->Colors[i]); + int distance = computeDistance(targetColor, indexedColor); + if (distance < closestColorDistance) { + closestColorIndex = i; + closestColorDistance = distance; + } + } + return closestColorIndex; +} + +int GifTranscoder::computeDistance(ColorARGB c1, ColorARGB c2) { + return SQUARE(RED(c1) - RED(c2)) + + SQUARE(GREEN(c1) - GREEN(c2)) + + SQUARE(BLUE(c1) - BLUE(c2)); +} + +ColorMapObject* GifTranscoder::getColorMap(GifFileType* gifIn) { + if (gifIn->Image.ColorMap) { + return gifIn->Image.ColorMap; + } + return gifIn->SColorMap; +} + +ColorARGB GifTranscoder::getColorARGB(ColorMapObject* colorMap, int transparentColorIndex, + GifByteType colorIndex) { + if (colorIndex == transparentColorIndex) { + return TRANSPARENT; + } + return gifColorToColorARGB(colorMap->Colors[colorIndex]); +} + +ColorARGB GifTranscoder::gifColorToColorARGB(const GifColorType& color) { + return MAKE_COLOR_ARGB(0xff, color.Red, color.Green, color.Blue); +} + +GifFilesCloser::~GifFilesCloser() { + if (mGifIn) { + DGifCloseFile(mGifIn, NULL); + mGifIn = NULL; + } + if (mGifOut) { + EGifCloseFile(mGifOut, NULL); + mGifOut = NULL; + } +} + +void GifFilesCloser::setGifIn(GifFileType* gifIn) { + ASSERT(mGifIn == NULL, "mGifIn is already set"); + mGifIn = gifIn; +} + +void GifFilesCloser::releaseGifIn() { + ASSERT(mGifIn != NULL, "mGifIn is already NULL"); + mGifIn = NULL; +} + +void GifFilesCloser::setGifOut(GifFileType* gifOut) { + ASSERT(mGifOut == NULL, "mGifOut is already set"); + mGifOut = gifOut; +} + +void GifFilesCloser::releaseGifOut() { + ASSERT(mGifOut != NULL, "mGifOut is already NULL"); + mGifOut = NULL; +} + +// JNI stuff + +jboolean transcode(JNIEnv* env, jobject clazz, jstring filePath, jstring outFilePath) { + const char* pathIn = env->GetStringUTFChars(filePath, JNI_FALSE); + const char* pathOut = env->GetStringUTFChars(outFilePath, JNI_FALSE); + + GifTranscoder transcoder; + int gifCode = transcoder.transcode(pathIn, pathOut); + + env->ReleaseStringUTFChars(filePath, pathIn); + env->ReleaseStringUTFChars(outFilePath, pathOut); + + return (gifCode == GIF_OK); +} + +const char *kClassPathName = "com/android/messaging/util/GifTranscoder"; + +JNINativeMethod kMethods[] = { + { "transcodeInternal", "(Ljava/lang/String;Ljava/lang/String;)Z", (void*)transcode }, +}; + +int registerNativeMethods(JNIEnv* env, const char* className, + JNINativeMethod* gMethods, int numMethods) { + jclass clazz = env->FindClass(className); + if (clazz == NULL) { + return JNI_FALSE; + } + if (env->RegisterNatives(clazz, gMethods, numMethods) < 0) { + return JNI_FALSE; + } + return JNI_TRUE; +} + +jint JNI_OnLoad(JavaVM* vm, void* reserved) { + JNIEnv* env; + if (vm->GetEnv(reinterpret_cast(&env), JNI_VERSION_1_6) != JNI_OK) { + return -1; + } + if (!registerNativeMethods(env, kClassPathName, + kMethods, sizeof(kMethods) / sizeof(kMethods[0]))) { + return -1; + } + return JNI_VERSION_1_6; +} diff --git a/app/src/main/jni/GifTranscoder.h b/app/src/main/jni/GifTranscoder.h new file mode 100644 index 0000000..39ecc24 --- /dev/null +++ b/app/src/main/jni/GifTranscoder.h @@ -0,0 +1,122 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef GIF_TRANSCODER_H +#define GIF_TRANSCODER_H + +#include + +#include "gif_lib.h" + +// 24-bit color with alpha, stored in order: A, R, G, B. +// The internal GIF render buffer stores pixels using this format. +typedef uint32_t ColorARGB; + +// Compresses a GIF (probably animated) so it can be sent via MMS, which generally has a 1 MB limit +// on attachments. GIF image data is already compressed (LZW), so to achieve further reduction in +// file size, we reduce the image dimensions. +// +// Helpful GIF references: +// GIF89A spec: http://www.w3.org/Graphics/GIF/spec-gif89a.txt +// What's in a GIF: http://giflib.sourceforge.net/whatsinagif/index.html +// +class GifTranscoder { +public: + GifTranscoder() {} + ~GifTranscoder() {} + + // Resizes a GIF's width and height to 50% of their original dimensions. The new file is + // written to pathOut. + // + // The image is resized using a box filter, which averages the colors in each 2x2 box of pixels + // in the source to generate the color of the pixel in the destination. + // + // Returns GIF_OK (1) on success, or GIF_ERROR (0) on failure. + int transcode(const char* pathIn, const char* pathOut); + +private: + // Implementation of the box filter algorithm. + static bool resizeBoxFilter(GifFileType* gifIn, GifFileType* gifOut); + + // Reads the raster data for the current image of the GIF. + static bool readImage(GifFileType* gifIn, GifByteType* rasterBits); + + // Renders the current image of the GIF into the supplied render buffer. + static bool renderImage(GifFileType* gifIn, + GifByteType* rasterBits, + int imageIndex, + int transparentColorIndex, + ColorARGB* renderBuffer, + ColorARGB bgColor, + GifImageDesc prevImageDimens, + int prevImageDisposalMode); + + // Fills a rectangle in the buffer with a solid color. + static void fillRect(ColorARGB* renderBuffer, + int imageWidth, + int imageHeight, + int left, + int top, + int width, + int height, + ColorARGB color); + + // Computes the color for the pixel (x,y) in the current image in the output GIF. + static GifByteType computeNewColorIndex(GifFileType* gifIn, + int transparentColorIndex, + ColorARGB* renderBuffer, + int x, + int y); + + // Computes the average color (by averaging the per-channel (ARGB) values). + static ColorARGB computeAverage(ColorARGB c1, ColorARGB c2, ColorARGB c3, ColorARGB c4); + + // Searches a color map for the color closest (Euclidean distance) to the target color. + static GifByteType findBestColor(ColorMapObject* colorMap, int transparentColorIndex, + ColorARGB targetColor); + + // Computes distance (squared) between 2 colors, considering each channel a separate dimension. + static int computeDistance(ColorARGB c1, ColorARGB c2); + + // Returns the local color map of the current image (if any), or else the global color map. + static ColorMapObject* getColorMap(GifFileType* gifIn); + + // Returns an indexed color from the color map. + static ColorARGB getColorARGB(ColorMapObject* colorMap, int transparentColorIndex, + GifByteType colorIndex); + + // Converts a 24-bit GIF color (RGB) to a 32-bit ARGB color. + static ColorARGB gifColorToColorARGB(const GifColorType& color); +}; + +// Wrapper class that automatically closes the GIF files when the wrapper goes out of scope. +class GifFilesCloser { +public: + GifFilesCloser() {} + ~GifFilesCloser(); + + void setGifIn(GifFileType* gifIn); + void releaseGifIn(); + + void setGifOut(GifFileType* gifOut); + void releaseGifOut(); + +private: + GifFileType* mGifIn = NULL; + GifFileType* mGifOut = NULL; +}; + +#endif // GIF_TRANSCODER_H diff --git a/res/color/tab_text_color.xml b/app/src/main/res/color/tab_text_color.xml similarity index 86% rename from res/color/tab_text_color.xml rename to app/src/main/res/color/tab_text_color.xml index 498d1e4..ab3dae9 100644 --- a/res/color/tab_text_color.xml +++ b/app/src/main/res/color/tab_text_color.xml @@ -16,8 +16,8 @@ --> - \ No newline at end of file + android:color="@color/looply_nav_inactive" /> + diff --git a/res/drawable-hdpi/contact_popup_background.9.png b/app/src/main/res/drawable-hdpi/contact_popup_background.9.png similarity index 100% rename from res/drawable-hdpi/contact_popup_background.9.png rename to app/src/main/res/drawable-hdpi/contact_popup_background.9.png diff --git a/res/drawable-hdpi/ic_failed_status_red.png b/app/src/main/res/drawable-hdpi/ic_failed_status_red.png similarity index 100% rename from res/drawable-hdpi/ic_failed_status_red.png rename to app/src/main/res/drawable-hdpi/ic_failed_status_red.png diff --git a/res/drawable-hdpi/ic_oobe_conv_list.png b/app/src/main/res/drawable-hdpi/ic_oobe_conv_list.png similarity index 100% rename from res/drawable-hdpi/ic_oobe_conv_list.png rename to app/src/main/res/drawable-hdpi/ic_oobe_conv_list.png diff --git a/res/drawable-hdpi/ic_oobe_freq_list.png b/app/src/main/res/drawable-hdpi/ic_oobe_freq_list.png similarity index 100% rename from res/drawable-hdpi/ic_oobe_freq_list.png rename to app/src/main/res/drawable-hdpi/ic_oobe_freq_list.png diff --git a/res/drawable-hdpi/ic_preview_pause.png b/app/src/main/res/drawable-hdpi/ic_preview_pause.png similarity index 100% rename from res/drawable-hdpi/ic_preview_pause.png rename to app/src/main/res/drawable-hdpi/ic_preview_pause.png diff --git a/res/drawable-hdpi/ic_preview_play.png b/app/src/main/res/drawable-hdpi/ic_preview_play.png similarity index 100% rename from res/drawable-hdpi/ic_preview_play.png rename to app/src/main/res/drawable-hdpi/ic_preview_play.png diff --git a/res/drawable-hdpi/ic_remove_light.png b/app/src/main/res/drawable-hdpi/ic_remove_light.png similarity index 100% rename from res/drawable-hdpi/ic_remove_light.png rename to app/src/main/res/drawable-hdpi/ic_remove_light.png diff --git a/res/drawable-hdpi/ic_sim_card_send.png b/app/src/main/res/drawable-hdpi/ic_sim_card_send.png similarity index 100% rename from res/drawable-hdpi/ic_sim_card_send.png rename to app/src/main/res/drawable-hdpi/ic_sim_card_send.png diff --git a/res/drawable-hdpi/ic_sms_delivery_ok.png b/app/src/main/res/drawable-hdpi/ic_sms_delivery_ok.png similarity index 100% rename from res/drawable-hdpi/ic_sms_delivery_ok.png rename to app/src/main/res/drawable-hdpi/ic_sms_delivery_ok.png diff --git a/res/drawable-hdpi/ic_sms_light.png b/app/src/main/res/drawable-hdpi/ic_sms_light.png similarity index 100% rename from res/drawable-hdpi/ic_sms_light.png rename to app/src/main/res/drawable-hdpi/ic_sms_light.png diff --git a/res/drawable-hdpi/ic_sms_multi_light.png b/app/src/main/res/drawable-hdpi/ic_sms_multi_light.png similarity index 100% rename from res/drawable-hdpi/ic_sms_multi_light.png rename to app/src/main/res/drawable-hdpi/ic_sms_multi_light.png diff --git a/res/drawable-hdpi/ic_widget_avatar_shadow.png b/app/src/main/res/drawable-hdpi/ic_widget_avatar_shadow.png similarity index 100% rename from res/drawable-hdpi/ic_widget_avatar_shadow.png rename to app/src/main/res/drawable-hdpi/ic_widget_avatar_shadow.png diff --git a/res/drawable-hdpi/permissions.png b/app/src/main/res/drawable-hdpi/permissions.png similarity index 100% rename from res/drawable-hdpi/permissions.png rename to app/src/main/res/drawable-hdpi/permissions.png diff --git a/res/drawable-hdpi/swipe_shadow.9.png b/app/src/main/res/drawable-hdpi/swipe_shadow.9.png similarity index 100% rename from res/drawable-hdpi/swipe_shadow.9.png rename to app/src/main/res/drawable-hdpi/swipe_shadow.9.png diff --git a/res/drawable-hdpi/swipe_shadow_drag.9.png b/app/src/main/res/drawable-hdpi/swipe_shadow_drag.9.png similarity index 100% rename from res/drawable-hdpi/swipe_shadow_drag.9.png rename to app/src/main/res/drawable-hdpi/swipe_shadow_drag.9.png diff --git a/res/drawable-hdpi/widget_hr.9.png b/app/src/main/res/drawable-hdpi/widget_hr.9.png similarity index 100% rename from res/drawable-hdpi/widget_hr.9.png rename to app/src/main/res/drawable-hdpi/widget_hr.9.png diff --git a/res/drawable-hdpi/widget_msg_bubble_incoming.9.png b/app/src/main/res/drawable-hdpi/widget_msg_bubble_incoming.9.png similarity index 100% rename from res/drawable-hdpi/widget_msg_bubble_incoming.9.png rename to app/src/main/res/drawable-hdpi/widget_msg_bubble_incoming.9.png diff --git a/res/drawable-hdpi/widget_msg_bubble_outgoing.9.png b/app/src/main/res/drawable-hdpi/widget_msg_bubble_outgoing.9.png similarity index 100% rename from res/drawable-hdpi/widget_msg_bubble_outgoing.9.png rename to app/src/main/res/drawable-hdpi/widget_msg_bubble_outgoing.9.png diff --git a/res/drawable-mdpi/contact_popup_background.9.png b/app/src/main/res/drawable-mdpi/contact_popup_background.9.png similarity index 100% rename from res/drawable-mdpi/contact_popup_background.9.png rename to app/src/main/res/drawable-mdpi/contact_popup_background.9.png diff --git a/res/drawable-mdpi/ic_failed_status_red.png b/app/src/main/res/drawable-mdpi/ic_failed_status_red.png similarity index 100% rename from res/drawable-mdpi/ic_failed_status_red.png rename to app/src/main/res/drawable-mdpi/ic_failed_status_red.png diff --git a/res/drawable-mdpi/ic_oobe_conv_list.png b/app/src/main/res/drawable-mdpi/ic_oobe_conv_list.png similarity index 100% rename from res/drawable-mdpi/ic_oobe_conv_list.png rename to app/src/main/res/drawable-mdpi/ic_oobe_conv_list.png diff --git a/res/drawable-mdpi/ic_oobe_freq_list.png b/app/src/main/res/drawable-mdpi/ic_oobe_freq_list.png similarity index 100% rename from res/drawable-mdpi/ic_oobe_freq_list.png rename to app/src/main/res/drawable-mdpi/ic_oobe_freq_list.png diff --git a/res/drawable-mdpi/ic_preview_pause.png b/app/src/main/res/drawable-mdpi/ic_preview_pause.png similarity index 100% rename from res/drawable-mdpi/ic_preview_pause.png rename to app/src/main/res/drawable-mdpi/ic_preview_pause.png diff --git a/res/drawable-mdpi/ic_preview_play.png b/app/src/main/res/drawable-mdpi/ic_preview_play.png similarity index 100% rename from res/drawable-mdpi/ic_preview_play.png rename to app/src/main/res/drawable-mdpi/ic_preview_play.png diff --git a/res/drawable-mdpi/ic_remove_light.png b/app/src/main/res/drawable-mdpi/ic_remove_light.png similarity index 100% rename from res/drawable-mdpi/ic_remove_light.png rename to app/src/main/res/drawable-mdpi/ic_remove_light.png diff --git a/res/drawable-mdpi/ic_sim_card_send.png b/app/src/main/res/drawable-mdpi/ic_sim_card_send.png similarity index 100% rename from res/drawable-mdpi/ic_sim_card_send.png rename to app/src/main/res/drawable-mdpi/ic_sim_card_send.png diff --git a/res/drawable-mdpi/ic_sms_delivery_ok.png b/app/src/main/res/drawable-mdpi/ic_sms_delivery_ok.png similarity index 100% rename from res/drawable-mdpi/ic_sms_delivery_ok.png rename to app/src/main/res/drawable-mdpi/ic_sms_delivery_ok.png diff --git a/res/drawable-mdpi/ic_sms_light.png b/app/src/main/res/drawable-mdpi/ic_sms_light.png similarity index 100% rename from res/drawable-mdpi/ic_sms_light.png rename to app/src/main/res/drawable-mdpi/ic_sms_light.png diff --git a/res/drawable-mdpi/ic_sms_multi_light.png b/app/src/main/res/drawable-mdpi/ic_sms_multi_light.png similarity index 100% rename from res/drawable-mdpi/ic_sms_multi_light.png rename to app/src/main/res/drawable-mdpi/ic_sms_multi_light.png diff --git a/res/drawable-mdpi/ic_widget_avatar_shadow.png b/app/src/main/res/drawable-mdpi/ic_widget_avatar_shadow.png similarity index 100% rename from res/drawable-mdpi/ic_widget_avatar_shadow.png rename to app/src/main/res/drawable-mdpi/ic_widget_avatar_shadow.png diff --git a/res/drawable-mdpi/permissions.png b/app/src/main/res/drawable-mdpi/permissions.png similarity index 100% rename from res/drawable-mdpi/permissions.png rename to app/src/main/res/drawable-mdpi/permissions.png diff --git a/res/drawable-mdpi/swipe_shadow.9.png b/app/src/main/res/drawable-mdpi/swipe_shadow.9.png similarity index 100% rename from res/drawable-mdpi/swipe_shadow.9.png rename to app/src/main/res/drawable-mdpi/swipe_shadow.9.png diff --git a/res/drawable-mdpi/swipe_shadow_drag.9.png b/app/src/main/res/drawable-mdpi/swipe_shadow_drag.9.png similarity index 100% rename from res/drawable-mdpi/swipe_shadow_drag.9.png rename to app/src/main/res/drawable-mdpi/swipe_shadow_drag.9.png diff --git a/res/drawable-mdpi/widget_hr.9.png b/app/src/main/res/drawable-mdpi/widget_hr.9.png similarity index 100% rename from res/drawable-mdpi/widget_hr.9.png rename to app/src/main/res/drawable-mdpi/widget_hr.9.png diff --git a/res/drawable-mdpi/widget_msg_bubble_incoming.9.png b/app/src/main/res/drawable-mdpi/widget_msg_bubble_incoming.9.png similarity index 100% rename from res/drawable-mdpi/widget_msg_bubble_incoming.9.png rename to app/src/main/res/drawable-mdpi/widget_msg_bubble_incoming.9.png diff --git a/res/drawable-mdpi/widget_msg_bubble_outgoing.9.png b/app/src/main/res/drawable-mdpi/widget_msg_bubble_outgoing.9.png similarity index 100% rename from res/drawable-mdpi/widget_msg_bubble_outgoing.9.png rename to app/src/main/res/drawable-mdpi/widget_msg_bubble_outgoing.9.png diff --git a/res/drawable-nodpi/messenger_widget_conversation_preview.png b/app/src/main/res/drawable-nodpi/messenger_widget_conversation_preview.png similarity index 100% rename from res/drawable-nodpi/messenger_widget_conversation_preview.png rename to app/src/main/res/drawable-nodpi/messenger_widget_conversation_preview.png diff --git a/res/drawable-nodpi/messenger_widget_preview.png b/app/src/main/res/drawable-nodpi/messenger_widget_preview.png similarity index 100% rename from res/drawable-nodpi/messenger_widget_preview.png rename to app/src/main/res/drawable-nodpi/messenger_widget_preview.png diff --git a/res/drawable-xhdpi/contact_popup_background.9.png b/app/src/main/res/drawable-xhdpi/contact_popup_background.9.png similarity index 100% rename from res/drawable-xhdpi/contact_popup_background.9.png rename to app/src/main/res/drawable-xhdpi/contact_popup_background.9.png diff --git a/res/drawable-xhdpi/ic_failed_status_red.png b/app/src/main/res/drawable-xhdpi/ic_failed_status_red.png similarity index 100% rename from res/drawable-xhdpi/ic_failed_status_red.png rename to app/src/main/res/drawable-xhdpi/ic_failed_status_red.png diff --git a/res/drawable-xhdpi/ic_oobe_conv_list.png b/app/src/main/res/drawable-xhdpi/ic_oobe_conv_list.png similarity index 100% rename from res/drawable-xhdpi/ic_oobe_conv_list.png rename to app/src/main/res/drawable-xhdpi/ic_oobe_conv_list.png diff --git a/res/drawable-xhdpi/ic_oobe_freq_list.png b/app/src/main/res/drawable-xhdpi/ic_oobe_freq_list.png similarity index 100% rename from res/drawable-xhdpi/ic_oobe_freq_list.png rename to app/src/main/res/drawable-xhdpi/ic_oobe_freq_list.png diff --git a/res/drawable-xhdpi/ic_preview_pause.png b/app/src/main/res/drawable-xhdpi/ic_preview_pause.png similarity index 100% rename from res/drawable-xhdpi/ic_preview_pause.png rename to app/src/main/res/drawable-xhdpi/ic_preview_pause.png diff --git a/res/drawable-xhdpi/ic_preview_play.png b/app/src/main/res/drawable-xhdpi/ic_preview_play.png similarity index 100% rename from res/drawable-xhdpi/ic_preview_play.png rename to app/src/main/res/drawable-xhdpi/ic_preview_play.png diff --git a/res/drawable-xhdpi/ic_remove_light.png b/app/src/main/res/drawable-xhdpi/ic_remove_light.png similarity index 100% rename from res/drawable-xhdpi/ic_remove_light.png rename to app/src/main/res/drawable-xhdpi/ic_remove_light.png diff --git a/res/drawable-xhdpi/ic_sim_card_send.png b/app/src/main/res/drawable-xhdpi/ic_sim_card_send.png similarity index 100% rename from res/drawable-xhdpi/ic_sim_card_send.png rename to app/src/main/res/drawable-xhdpi/ic_sim_card_send.png diff --git a/res/drawable-xhdpi/ic_sms_delivery_ok.png b/app/src/main/res/drawable-xhdpi/ic_sms_delivery_ok.png similarity index 100% rename from res/drawable-xhdpi/ic_sms_delivery_ok.png rename to app/src/main/res/drawable-xhdpi/ic_sms_delivery_ok.png diff --git a/res/drawable-xhdpi/ic_sms_light.png b/app/src/main/res/drawable-xhdpi/ic_sms_light.png similarity index 100% rename from res/drawable-xhdpi/ic_sms_light.png rename to app/src/main/res/drawable-xhdpi/ic_sms_light.png diff --git a/res/drawable-xhdpi/ic_sms_multi_light.png b/app/src/main/res/drawable-xhdpi/ic_sms_multi_light.png similarity index 100% rename from res/drawable-xhdpi/ic_sms_multi_light.png rename to app/src/main/res/drawable-xhdpi/ic_sms_multi_light.png diff --git a/res/drawable-xhdpi/ic_widget_avatar_shadow.png b/app/src/main/res/drawable-xhdpi/ic_widget_avatar_shadow.png similarity index 100% rename from res/drawable-xhdpi/ic_widget_avatar_shadow.png rename to app/src/main/res/drawable-xhdpi/ic_widget_avatar_shadow.png diff --git a/res/drawable-xhdpi/permissions.png b/app/src/main/res/drawable-xhdpi/permissions.png similarity index 100% rename from res/drawable-xhdpi/permissions.png rename to app/src/main/res/drawable-xhdpi/permissions.png diff --git a/res/drawable-xhdpi/swipe_shadow.9.png b/app/src/main/res/drawable-xhdpi/swipe_shadow.9.png similarity index 100% rename from res/drawable-xhdpi/swipe_shadow.9.png rename to app/src/main/res/drawable-xhdpi/swipe_shadow.9.png diff --git a/res/drawable-xhdpi/swipe_shadow_drag.9.png b/app/src/main/res/drawable-xhdpi/swipe_shadow_drag.9.png similarity index 100% rename from res/drawable-xhdpi/swipe_shadow_drag.9.png rename to app/src/main/res/drawable-xhdpi/swipe_shadow_drag.9.png diff --git a/res/drawable-xhdpi/widget_hr.9.png b/app/src/main/res/drawable-xhdpi/widget_hr.9.png similarity index 100% rename from res/drawable-xhdpi/widget_hr.9.png rename to app/src/main/res/drawable-xhdpi/widget_hr.9.png diff --git a/res/drawable-xhdpi/widget_msg_bubble_incoming.9.png b/app/src/main/res/drawable-xhdpi/widget_msg_bubble_incoming.9.png similarity index 100% rename from res/drawable-xhdpi/widget_msg_bubble_incoming.9.png rename to app/src/main/res/drawable-xhdpi/widget_msg_bubble_incoming.9.png diff --git a/res/drawable-xhdpi/widget_msg_bubble_outgoing.9.png b/app/src/main/res/drawable-xhdpi/widget_msg_bubble_outgoing.9.png similarity index 100% rename from res/drawable-xhdpi/widget_msg_bubble_outgoing.9.png rename to app/src/main/res/drawable-xhdpi/widget_msg_bubble_outgoing.9.png diff --git a/res/drawable-xxhdpi/contact_popup_background.9.png b/app/src/main/res/drawable-xxhdpi/contact_popup_background.9.png similarity index 100% rename from res/drawable-xxhdpi/contact_popup_background.9.png rename to app/src/main/res/drawable-xxhdpi/contact_popup_background.9.png diff --git a/res/drawable-xxhdpi/ic_failed_status_red.png b/app/src/main/res/drawable-xxhdpi/ic_failed_status_red.png similarity index 100% rename from res/drawable-xxhdpi/ic_failed_status_red.png rename to app/src/main/res/drawable-xxhdpi/ic_failed_status_red.png diff --git a/res/drawable-xxhdpi/ic_oobe_conv_list.png b/app/src/main/res/drawable-xxhdpi/ic_oobe_conv_list.png similarity index 100% rename from res/drawable-xxhdpi/ic_oobe_conv_list.png rename to app/src/main/res/drawable-xxhdpi/ic_oobe_conv_list.png diff --git a/res/drawable-xxhdpi/ic_oobe_freq_list.png b/app/src/main/res/drawable-xxhdpi/ic_oobe_freq_list.png similarity index 100% rename from res/drawable-xxhdpi/ic_oobe_freq_list.png rename to app/src/main/res/drawable-xxhdpi/ic_oobe_freq_list.png diff --git a/res/drawable-xxhdpi/ic_preview_pause.png b/app/src/main/res/drawable-xxhdpi/ic_preview_pause.png similarity index 100% rename from res/drawable-xxhdpi/ic_preview_pause.png rename to app/src/main/res/drawable-xxhdpi/ic_preview_pause.png diff --git a/res/drawable-xxhdpi/ic_preview_play.png b/app/src/main/res/drawable-xxhdpi/ic_preview_play.png similarity index 100% rename from res/drawable-xxhdpi/ic_preview_play.png rename to app/src/main/res/drawable-xxhdpi/ic_preview_play.png diff --git a/res/drawable-xxhdpi/ic_remove_light.png b/app/src/main/res/drawable-xxhdpi/ic_remove_light.png similarity index 100% rename from res/drawable-xxhdpi/ic_remove_light.png rename to app/src/main/res/drawable-xxhdpi/ic_remove_light.png diff --git a/res/drawable-xxhdpi/ic_sim_card_send.png b/app/src/main/res/drawable-xxhdpi/ic_sim_card_send.png similarity index 100% rename from res/drawable-xxhdpi/ic_sim_card_send.png rename to app/src/main/res/drawable-xxhdpi/ic_sim_card_send.png diff --git a/res/drawable-xxhdpi/ic_sms_delivery_ok.png b/app/src/main/res/drawable-xxhdpi/ic_sms_delivery_ok.png similarity index 100% rename from res/drawable-xxhdpi/ic_sms_delivery_ok.png rename to app/src/main/res/drawable-xxhdpi/ic_sms_delivery_ok.png diff --git a/res/drawable-xxhdpi/ic_sms_light.png b/app/src/main/res/drawable-xxhdpi/ic_sms_light.png similarity index 100% rename from res/drawable-xxhdpi/ic_sms_light.png rename to app/src/main/res/drawable-xxhdpi/ic_sms_light.png diff --git a/res/drawable-xxhdpi/ic_sms_multi_light.png b/app/src/main/res/drawable-xxhdpi/ic_sms_multi_light.png similarity index 100% rename from res/drawable-xxhdpi/ic_sms_multi_light.png rename to app/src/main/res/drawable-xxhdpi/ic_sms_multi_light.png diff --git a/res/drawable-xxhdpi/ic_widget_avatar_shadow.png b/app/src/main/res/drawable-xxhdpi/ic_widget_avatar_shadow.png similarity index 100% rename from res/drawable-xxhdpi/ic_widget_avatar_shadow.png rename to app/src/main/res/drawable-xxhdpi/ic_widget_avatar_shadow.png diff --git a/res/drawable-xxhdpi/permissions.png b/app/src/main/res/drawable-xxhdpi/permissions.png similarity index 100% rename from res/drawable-xxhdpi/permissions.png rename to app/src/main/res/drawable-xxhdpi/permissions.png diff --git a/res/drawable-xxhdpi/swipe_shadow.9.png b/app/src/main/res/drawable-xxhdpi/swipe_shadow.9.png similarity index 100% rename from res/drawable-xxhdpi/swipe_shadow.9.png rename to app/src/main/res/drawable-xxhdpi/swipe_shadow.9.png diff --git a/res/drawable-xxhdpi/swipe_shadow_drag.9.png b/app/src/main/res/drawable-xxhdpi/swipe_shadow_drag.9.png similarity index 100% rename from res/drawable-xxhdpi/swipe_shadow_drag.9.png rename to app/src/main/res/drawable-xxhdpi/swipe_shadow_drag.9.png diff --git a/res/drawable-xxhdpi/widget_hr.9.png b/app/src/main/res/drawable-xxhdpi/widget_hr.9.png similarity index 100% rename from res/drawable-xxhdpi/widget_hr.9.png rename to app/src/main/res/drawable-xxhdpi/widget_hr.9.png diff --git a/res/drawable-xxhdpi/widget_msg_bubble_incoming.9.png b/app/src/main/res/drawable-xxhdpi/widget_msg_bubble_incoming.9.png similarity index 100% rename from res/drawable-xxhdpi/widget_msg_bubble_incoming.9.png rename to app/src/main/res/drawable-xxhdpi/widget_msg_bubble_incoming.9.png diff --git a/res/drawable-xxhdpi/widget_msg_bubble_outgoing.9.png b/app/src/main/res/drawable-xxhdpi/widget_msg_bubble_outgoing.9.png similarity index 100% rename from res/drawable-xxhdpi/widget_msg_bubble_outgoing.9.png rename to app/src/main/res/drawable-xxhdpi/widget_msg_bubble_outgoing.9.png diff --git a/res/drawable-xxxhdpi/contact_popup_background.9.png b/app/src/main/res/drawable-xxxhdpi/contact_popup_background.9.png similarity index 100% rename from res/drawable-xxxhdpi/contact_popup_background.9.png rename to app/src/main/res/drawable-xxxhdpi/contact_popup_background.9.png diff --git a/res/drawable-xxxhdpi/ic_failed_status_red.png b/app/src/main/res/drawable-xxxhdpi/ic_failed_status_red.png similarity index 100% rename from res/drawable-xxxhdpi/ic_failed_status_red.png rename to app/src/main/res/drawable-xxxhdpi/ic_failed_status_red.png diff --git a/res/drawable-xxxhdpi/ic_oobe_conv_list.png b/app/src/main/res/drawable-xxxhdpi/ic_oobe_conv_list.png similarity index 100% rename from res/drawable-xxxhdpi/ic_oobe_conv_list.png rename to app/src/main/res/drawable-xxxhdpi/ic_oobe_conv_list.png diff --git a/res/drawable-xxxhdpi/ic_oobe_freq_list.png b/app/src/main/res/drawable-xxxhdpi/ic_oobe_freq_list.png similarity index 100% rename from res/drawable-xxxhdpi/ic_oobe_freq_list.png rename to app/src/main/res/drawable-xxxhdpi/ic_oobe_freq_list.png diff --git a/res/drawable-xxxhdpi/ic_preview_pause.png b/app/src/main/res/drawable-xxxhdpi/ic_preview_pause.png similarity index 100% rename from res/drawable-xxxhdpi/ic_preview_pause.png rename to app/src/main/res/drawable-xxxhdpi/ic_preview_pause.png diff --git a/res/drawable-xxxhdpi/ic_preview_play.png b/app/src/main/res/drawable-xxxhdpi/ic_preview_play.png similarity index 100% rename from res/drawable-xxxhdpi/ic_preview_play.png rename to app/src/main/res/drawable-xxxhdpi/ic_preview_play.png diff --git a/res/drawable-xxxhdpi/ic_remove_light.png b/app/src/main/res/drawable-xxxhdpi/ic_remove_light.png similarity index 100% rename from res/drawable-xxxhdpi/ic_remove_light.png rename to app/src/main/res/drawable-xxxhdpi/ic_remove_light.png diff --git a/res/drawable-xxxhdpi/ic_sim_card_send.png b/app/src/main/res/drawable-xxxhdpi/ic_sim_card_send.png similarity index 100% rename from res/drawable-xxxhdpi/ic_sim_card_send.png rename to app/src/main/res/drawable-xxxhdpi/ic_sim_card_send.png diff --git a/res/drawable-xxxhdpi/ic_sms_delivery_ok.png b/app/src/main/res/drawable-xxxhdpi/ic_sms_delivery_ok.png similarity index 100% rename from res/drawable-xxxhdpi/ic_sms_delivery_ok.png rename to app/src/main/res/drawable-xxxhdpi/ic_sms_delivery_ok.png diff --git a/res/drawable-xxxhdpi/ic_sms_light.png b/app/src/main/res/drawable-xxxhdpi/ic_sms_light.png similarity index 100% rename from res/drawable-xxxhdpi/ic_sms_light.png rename to app/src/main/res/drawable-xxxhdpi/ic_sms_light.png diff --git a/res/drawable-xxxhdpi/ic_sms_multi_light.png b/app/src/main/res/drawable-xxxhdpi/ic_sms_multi_light.png similarity index 100% rename from res/drawable-xxxhdpi/ic_sms_multi_light.png rename to app/src/main/res/drawable-xxxhdpi/ic_sms_multi_light.png diff --git a/res/drawable-xxxhdpi/ic_widget_avatar_shadow.png b/app/src/main/res/drawable-xxxhdpi/ic_widget_avatar_shadow.png similarity index 100% rename from res/drawable-xxxhdpi/ic_widget_avatar_shadow.png rename to app/src/main/res/drawable-xxxhdpi/ic_widget_avatar_shadow.png diff --git a/res/drawable-xxxhdpi/permissions.png b/app/src/main/res/drawable-xxxhdpi/permissions.png similarity index 100% rename from res/drawable-xxxhdpi/permissions.png rename to app/src/main/res/drawable-xxxhdpi/permissions.png diff --git a/res/drawable-xxxhdpi/swipe_shadow.9.png b/app/src/main/res/drawable-xxxhdpi/swipe_shadow.9.png similarity index 100% rename from res/drawable-xxxhdpi/swipe_shadow.9.png rename to app/src/main/res/drawable-xxxhdpi/swipe_shadow.9.png diff --git a/res/drawable-xxxhdpi/swipe_shadow_drag.9.png b/app/src/main/res/drawable-xxxhdpi/swipe_shadow_drag.9.png similarity index 100% rename from res/drawable-xxxhdpi/swipe_shadow_drag.9.png rename to app/src/main/res/drawable-xxxhdpi/swipe_shadow_drag.9.png diff --git a/res/drawable-xxxhdpi/widget_hr.9.png b/app/src/main/res/drawable-xxxhdpi/widget_hr.9.png similarity index 100% rename from res/drawable-xxxhdpi/widget_hr.9.png rename to app/src/main/res/drawable-xxxhdpi/widget_hr.9.png diff --git a/res/drawable-xxxhdpi/widget_msg_bubble_incoming.9.png b/app/src/main/res/drawable-xxxhdpi/widget_msg_bubble_incoming.9.png similarity index 100% rename from res/drawable-xxxhdpi/widget_msg_bubble_incoming.9.png rename to app/src/main/res/drawable-xxxhdpi/widget_msg_bubble_incoming.9.png diff --git a/res/drawable-xxxhdpi/widget_msg_bubble_outgoing.9.png b/app/src/main/res/drawable-xxxhdpi/widget_msg_bubble_outgoing.9.png similarity index 100% rename from res/drawable-xxxhdpi/widget_msg_bubble_outgoing.9.png rename to app/src/main/res/drawable-xxxhdpi/widget_msg_bubble_outgoing.9.png diff --git a/res/drawable/attachment_audio_preview_background.xml b/app/src/main/res/drawable/attachment_audio_preview_background.xml similarity index 100% rename from res/drawable/attachment_audio_preview_background.xml rename to app/src/main/res/drawable/attachment_audio_preview_background.xml diff --git a/res/drawable/attachment_image_placeholder_background.xml b/app/src/main/res/drawable/attachment_image_placeholder_background.xml similarity index 100% rename from res/drawable/attachment_image_placeholder_background.xml rename to app/src/main/res/drawable/attachment_image_placeholder_background.xml diff --git a/res/drawable/attachment_more_items_background.xml b/app/src/main/res/drawable/attachment_more_items_background.xml similarity index 100% rename from res/drawable/attachment_more_items_background.xml rename to app/src/main/res/drawable/attachment_more_items_background.xml diff --git a/res/drawable/attachment_vcard_preview_background.xml b/app/src/main/res/drawable/attachment_vcard_preview_background.xml similarity index 100% rename from res/drawable/attachment_vcard_preview_background.xml rename to app/src/main/res/drawable/attachment_vcard_preview_background.xml diff --git a/res/drawable/audio_progress_bar_background_incoming.xml b/app/src/main/res/drawable/audio_progress_bar_background_incoming.xml similarity index 100% rename from res/drawable/audio_progress_bar_background_incoming.xml rename to app/src/main/res/drawable/audio_progress_bar_background_incoming.xml diff --git a/res/drawable/audio_progress_bar_background_outgoing.xml b/app/src/main/res/drawable/audio_progress_bar_background_outgoing.xml similarity index 100% rename from res/drawable/audio_progress_bar_background_outgoing.xml rename to app/src/main/res/drawable/audio_progress_bar_background_outgoing.xml diff --git a/res/drawable/audio_progress_bar_progress.xml b/app/src/main/res/drawable/audio_progress_bar_progress.xml similarity index 100% rename from res/drawable/audio_progress_bar_progress.xml rename to app/src/main/res/drawable/audio_progress_bar_progress.xml diff --git a/res/drawable/audio_record_control_button_background.xml b/app/src/main/res/drawable/audio_record_control_button_background.xml similarity index 100% rename from res/drawable/audio_record_control_button_background.xml rename to app/src/main/res/drawable/audio_record_control_button_background.xml diff --git a/res/drawable/chips_dropdown_background.xml b/app/src/main/res/drawable/chips_dropdown_background.xml similarity index 100% rename from res/drawable/chips_dropdown_background.xml rename to app/src/main/res/drawable/chips_dropdown_background.xml diff --git a/res/drawable/chips_dropdown_text_color.xml b/app/src/main/res/drawable/chips_dropdown_text_color.xml similarity index 100% rename from res/drawable/chips_dropdown_text_color.xml rename to app/src/main/res/drawable/chips_dropdown_text_color.xml diff --git a/res/drawable/compose_chips_divider_gradient.xml b/app/src/main/res/drawable/compose_chips_divider_gradient.xml similarity index 100% rename from res/drawable/compose_chips_divider_gradient.xml rename to app/src/main/res/drawable/compose_chips_divider_gradient.xml diff --git a/res/drawable/contact_picker_tab_background_selector.xml b/app/src/main/res/drawable/contact_picker_tab_background_selector.xml similarity index 100% rename from res/drawable/contact_picker_tab_background_selector.xml rename to app/src/main/res/drawable/contact_picker_tab_background_selector.xml diff --git a/res/drawable/contacts_fastscroll_label_left.xml b/app/src/main/res/drawable/contacts_fastscroll_label_left.xml similarity index 100% rename from res/drawable/contacts_fastscroll_label_left.xml rename to app/src/main/res/drawable/contacts_fastscroll_label_left.xml diff --git a/res/drawable/contacts_fastscroll_label_right.xml b/app/src/main/res/drawable/contacts_fastscroll_label_right.xml similarity index 100% rename from res/drawable/contacts_fastscroll_label_right.xml rename to app/src/main/res/drawable/contacts_fastscroll_label_right.xml diff --git a/res/drawable/conversation_compose_divider_gradient.xml b/app/src/main/res/drawable/conversation_compose_divider_gradient.xml similarity index 100% rename from res/drawable/conversation_compose_divider_gradient.xml rename to app/src/main/res/drawable/conversation_compose_divider_gradient.xml diff --git a/res/drawable/fastscroll_preview_left.xml b/app/src/main/res/drawable/fastscroll_preview_left.xml similarity index 100% rename from res/drawable/fastscroll_preview_left.xml rename to app/src/main/res/drawable/fastscroll_preview_left.xml diff --git a/res/drawable/fastscroll_preview_right.xml b/app/src/main/res/drawable/fastscroll_preview_right.xml similarity index 100% rename from res/drawable/fastscroll_preview_right.xml rename to app/src/main/res/drawable/fastscroll_preview_right.xml diff --git a/res/drawable/fastscroll_thumb.xml b/app/src/main/res/drawable/fastscroll_thumb.xml similarity index 100% rename from res/drawable/fastscroll_thumb.xml rename to app/src/main/res/drawable/fastscroll_thumb.xml diff --git a/res/drawable/fastscroll_thumb_pressed.xml b/app/src/main/res/drawable/fastscroll_thumb_pressed.xml similarity index 100% rename from res/drawable/fastscroll_thumb_pressed.xml rename to app/src/main/res/drawable/fastscroll_thumb_pressed.xml diff --git a/res/drawable/fastscroll_track.xml b/app/src/main/res/drawable/fastscroll_track.xml similarity index 100% rename from res/drawable/fastscroll_track.xml rename to app/src/main/res/drawable/fastscroll_track.xml diff --git a/res/drawable/gallery_checkbox_selector.xml b/app/src/main/res/drawable/gallery_checkbox_selector.xml similarity index 100% rename from res/drawable/gallery_checkbox_selector.xml rename to app/src/main/res/drawable/gallery_checkbox_selector.xml diff --git a/app/src/main/res/drawable/home_bg_chip.xml b/app/src/main/res/drawable/home_bg_chip.xml new file mode 100644 index 0000000..d1dc60a --- /dev/null +++ b/app/src/main/res/drawable/home_bg_chip.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/res/drawable/home_bg_circle.xml b/app/src/main/res/drawable/home_bg_circle.xml new file mode 100644 index 0000000..9823f31 --- /dev/null +++ b/app/src/main/res/drawable/home_bg_circle.xml @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/home_bg_contacts_card.xml b/app/src/main/res/drawable/home_bg_contacts_card.xml new file mode 100644 index 0000000..0d7d0ba --- /dev/null +++ b/app/src/main/res/drawable/home_bg_contacts_card.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/res/drawable/home_bg_dock_fab.xml b/app/src/main/res/drawable/home_bg_dock_fab.xml new file mode 100644 index 0000000..10c0629 --- /dev/null +++ b/app/src/main/res/drawable/home_bg_dock_fab.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/home_bg_dock_pill.xml b/app/src/main/res/drawable/home_bg_dock_pill.xml new file mode 100644 index 0000000..e2687aa --- /dev/null +++ b/app/src/main/res/drawable/home_bg_dock_pill.xml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/home_bg_fab.xml b/app/src/main/res/drawable/home_bg_fab.xml new file mode 100644 index 0000000..d7021b7 --- /dev/null +++ b/app/src/main/res/drawable/home_bg_fab.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/res/drawable/home_bg_main_nav.xml b/app/src/main/res/drawable/home_bg_main_nav.xml new file mode 100644 index 0000000..42b288b --- /dev/null +++ b/app/src/main/res/drawable/home_bg_main_nav.xml @@ -0,0 +1,8 @@ + + + + + diff --git a/app/src/main/res/drawable/home_bg_nav_active.xml b/app/src/main/res/drawable/home_bg_nav_active.xml new file mode 100644 index 0000000..dab197c --- /dev/null +++ b/app/src/main/res/drawable/home_bg_nav_active.xml @@ -0,0 +1,9 @@ + + + + + + diff --git a/app/src/main/res/drawable/home_bg_nav_active_primary.xml b/app/src/main/res/drawable/home_bg_nav_active_primary.xml new file mode 100644 index 0000000..aadc84e --- /dev/null +++ b/app/src/main/res/drawable/home_bg_nav_active_primary.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/res/drawable/home_bg_pill.xml b/app/src/main/res/drawable/home_bg_pill.xml new file mode 100644 index 0000000..519f83f --- /dev/null +++ b/app/src/main/res/drawable/home_bg_pill.xml @@ -0,0 +1,9 @@ + + + + + + diff --git a/app/src/main/res/drawable/home_bg_pin_active.xml b/app/src/main/res/drawable/home_bg_pin_active.xml new file mode 100644 index 0000000..6af3439 --- /dev/null +++ b/app/src/main/res/drawable/home_bg_pin_active.xml @@ -0,0 +1,5 @@ + + + + diff --git a/app/src/main/res/drawable/home_bg_pin_inactive.xml b/app/src/main/res/drawable/home_bg_pin_inactive.xml new file mode 100644 index 0000000..aa96a19 --- /dev/null +++ b/app/src/main/res/drawable/home_bg_pin_inactive.xml @@ -0,0 +1,5 @@ + + + + diff --git a/app/src/main/res/drawable/home_bg_pinned_preview_bubble.xml b/app/src/main/res/drawable/home_bg_pinned_preview_bubble.xml new file mode 100644 index 0000000..317c357 --- /dev/null +++ b/app/src/main/res/drawable/home_bg_pinned_preview_bubble.xml @@ -0,0 +1,9 @@ + + + + + + diff --git a/app/src/main/res/drawable/home_bg_pinned_remove.xml b/app/src/main/res/drawable/home_bg_pinned_remove.xml new file mode 100644 index 0000000..9210db9 --- /dev/null +++ b/app/src/main/res/drawable/home_bg_pinned_remove.xml @@ -0,0 +1,5 @@ + + + + diff --git a/app/src/main/res/drawable/home_bg_popover.xml b/app/src/main/res/drawable/home_bg_popover.xml new file mode 100644 index 0000000..18913cb --- /dev/null +++ b/app/src/main/res/drawable/home_bg_popover.xml @@ -0,0 +1,9 @@ + + + + + + diff --git a/app/src/main/res/drawable/home_bg_popover_item.xml b/app/src/main/res/drawable/home_bg_popover_item.xml new file mode 100644 index 0000000..b34543c --- /dev/null +++ b/app/src/main/res/drawable/home_bg_popover_item.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/home_bg_search_bar_outer.xml b/app/src/main/res/drawable/home_bg_search_bar_outer.xml new file mode 100644 index 0000000..4b23ace --- /dev/null +++ b/app/src/main/res/drawable/home_bg_search_bar_outer.xml @@ -0,0 +1,11 @@ + + + + diff --git a/app/src/main/res/drawable/home_bg_search_field.xml b/app/src/main/res/drawable/home_bg_search_field.xml new file mode 100644 index 0000000..ba0d60a --- /dev/null +++ b/app/src/main/res/drawable/home_bg_search_field.xml @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/home_bg_search_field_inner.xml b/app/src/main/res/drawable/home_bg_search_field_inner.xml new file mode 100644 index 0000000..7d68f05 --- /dev/null +++ b/app/src/main/res/drawable/home_bg_search_field_inner.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/res/drawable/home_bg_selection_ring.xml b/app/src/main/res/drawable/home_bg_selection_ring.xml new file mode 100644 index 0000000..7c4d680 --- /dev/null +++ b/app/src/main/res/drawable/home_bg_selection_ring.xml @@ -0,0 +1,16 @@ + + + + + + + + + + diff --git a/app/src/main/res/drawable/home_bg_selection_ring_checked.xml b/app/src/main/res/drawable/home_bg_selection_ring_checked.xml new file mode 100644 index 0000000..a7b2532 --- /dev/null +++ b/app/src/main/res/drawable/home_bg_selection_ring_checked.xml @@ -0,0 +1,5 @@ + + + + diff --git a/app/src/main/res/drawable/home_bg_sim_badge.xml b/app/src/main/res/drawable/home_bg_sim_badge.xml new file mode 100644 index 0000000..c119efb --- /dev/null +++ b/app/src/main/res/drawable/home_bg_sim_badge.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/res/drawable/home_bg_unread_dot.xml b/app/src/main/res/drawable/home_bg_unread_dot.xml new file mode 100644 index 0000000..a7b2532 --- /dev/null +++ b/app/src/main/res/drawable/home_bg_unread_dot.xml @@ -0,0 +1,5 @@ + + + + diff --git a/app/src/main/res/drawable/home_pinned_preview_tail.xml b/app/src/main/res/drawable/home_pinned_preview_tail.xml new file mode 100644 index 0000000..793c89c --- /dev/null +++ b/app/src/main/res/drawable/home_pinned_preview_tail.xml @@ -0,0 +1,17 @@ + + + + + + diff --git a/res/drawable/ic_add_white.xml b/app/src/main/res/drawable/ic_add_white.xml similarity index 100% rename from res/drawable/ic_add_white.xml rename to app/src/main/res/drawable/ic_add_white.xml diff --git a/res/drawable/ic_archive_small_dark.xml b/app/src/main/res/drawable/ic_archive_small_dark.xml similarity index 100% rename from res/drawable/ic_archive_small_dark.xml rename to app/src/main/res/drawable/ic_archive_small_dark.xml diff --git a/res/drawable/ic_archive_undo_small_dark.xml b/app/src/main/res/drawable/ic_archive_undo_small_dark.xml similarity index 100% rename from res/drawable/ic_archive_undo_small_dark.xml rename to app/src/main/res/drawable/ic_archive_undo_small_dark.xml diff --git a/res/drawable/ic_arrow_back_light.xml b/app/src/main/res/drawable/ic_arrow_back_light.xml similarity index 100% rename from res/drawable/ic_arrow_back_light.xml rename to app/src/main/res/drawable/ic_arrow_back_light.xml diff --git a/res/drawable/ic_attachment_dark.xml b/app/src/main/res/drawable/ic_attachment_dark.xml similarity index 100% rename from res/drawable/ic_attachment_dark.xml rename to app/src/main/res/drawable/ic_attachment_dark.xml diff --git a/res/drawable/ic_audio_light.xml b/app/src/main/res/drawable/ic_audio_light.xml similarity index 100% rename from res/drawable/ic_audio_light.xml rename to app/src/main/res/drawable/ic_audio_light.xml diff --git a/res/drawable/ic_camera_light.xml b/app/src/main/res/drawable/ic_camera_light.xml similarity index 100% rename from res/drawable/ic_camera_light.xml rename to app/src/main/res/drawable/ic_camera_light.xml diff --git a/res/drawable/ic_cancel_small_light.xml b/app/src/main/res/drawable/ic_cancel_small_light.xml similarity index 100% rename from res/drawable/ic_cancel_small_light.xml rename to app/src/main/res/drawable/ic_cancel_small_light.xml diff --git a/res/drawable/ic_checkbox_blank_light.xml b/app/src/main/res/drawable/ic_checkbox_blank_light.xml similarity index 100% rename from res/drawable/ic_checkbox_blank_light.xml rename to app/src/main/res/drawable/ic_checkbox_blank_light.xml diff --git a/res/drawable/ic_checkbox_light.xml b/app/src/main/res/drawable/ic_checkbox_light.xml similarity index 100% rename from res/drawable/ic_checkbox_light.xml rename to app/src/main/res/drawable/ic_checkbox_light.xml diff --git a/res/drawable/ic_checkmark_circle_blue.xml b/app/src/main/res/drawable/ic_checkmark_circle_blue.xml similarity index 100% rename from res/drawable/ic_checkmark_circle_blue.xml rename to app/src/main/res/drawable/ic_checkmark_circle_blue.xml diff --git a/app/src/main/res/drawable/ic_checkmark_circle_primary.xml b/app/src/main/res/drawable/ic_checkmark_circle_primary.xml new file mode 100644 index 0000000..3118d86 --- /dev/null +++ b/app/src/main/res/drawable/ic_checkmark_circle_primary.xml @@ -0,0 +1,10 @@ + + + diff --git a/res/drawable/ic_checkmark_light.xml b/app/src/main/res/drawable/ic_checkmark_light.xml similarity index 100% rename from res/drawable/ic_checkmark_light.xml rename to app/src/main/res/drawable/ic_checkmark_light.xml diff --git a/res/drawable/ic_content_copy_light.xml b/app/src/main/res/drawable/ic_content_copy_light.xml similarity index 100% rename from res/drawable/ic_content_copy_light.xml rename to app/src/main/res/drawable/ic_content_copy_light.xml diff --git a/res/drawable/ic_delete_small_dark.xml b/app/src/main/res/drawable/ic_delete_small_dark.xml similarity index 100% rename from res/drawable/ic_delete_small_dark.xml rename to app/src/main/res/drawable/ic_delete_small_dark.xml diff --git a/res/drawable/ic_dnd_on_light.xml b/app/src/main/res/drawable/ic_dnd_on_light.xml similarity index 100% rename from res/drawable/ic_dnd_on_light.xml rename to app/src/main/res/drawable/ic_dnd_on_light.xml diff --git a/res/drawable/ic_failed_light.xml b/app/src/main/res/drawable/ic_failed_light.xml similarity index 100% rename from res/drawable/ic_failed_light.xml rename to app/src/main/res/drawable/ic_failed_light.xml diff --git a/res/drawable/ic_file_download_light.xml b/app/src/main/res/drawable/ic_file_download_light.xml similarity index 100% rename from res/drawable/ic_file_download_light.xml rename to app/src/main/res/drawable/ic_file_download_light.xml diff --git a/res/drawable/ic_forward_light.xml b/app/src/main/res/drawable/ic_forward_light.xml similarity index 100% rename from res/drawable/ic_forward_light.xml rename to app/src/main/res/drawable/ic_forward_light.xml diff --git a/app/src/main/res/drawable/ic_home_add.xml b/app/src/main/res/drawable/ic_home_add.xml new file mode 100644 index 0000000..1986445 --- /dev/null +++ b/app/src/main/res/drawable/ic_home_add.xml @@ -0,0 +1,18 @@ + + + + + diff --git a/app/src/main/res/drawable/ic_home_check.xml b/app/src/main/res/drawable/ic_home_check.xml new file mode 100644 index 0000000..fa72afb --- /dev/null +++ b/app/src/main/res/drawable/ic_home_check.xml @@ -0,0 +1,6 @@ + + + + diff --git a/app/src/main/res/drawable/ic_home_chevron.xml b/app/src/main/res/drawable/ic_home_chevron.xml new file mode 100644 index 0000000..ae9ac87 --- /dev/null +++ b/app/src/main/res/drawable/ic_home_chevron.xml @@ -0,0 +1,10 @@ + + + + diff --git a/app/src/main/res/drawable/ic_home_compose.xml b/app/src/main/res/drawable/ic_home_compose.xml new file mode 100644 index 0000000..6ac77a2 --- /dev/null +++ b/app/src/main/res/drawable/ic_home_compose.xml @@ -0,0 +1,7 @@ + + + + + diff --git a/app/src/main/res/drawable/ic_home_compose_line.xml b/app/src/main/res/drawable/ic_home_compose_line.xml new file mode 100644 index 0000000..9e39506 --- /dev/null +++ b/app/src/main/res/drawable/ic_home_compose_line.xml @@ -0,0 +1,25 @@ + + + + + + diff --git a/app/src/main/res/drawable/ic_home_filter.xml b/app/src/main/res/drawable/ic_home_filter.xml new file mode 100644 index 0000000..6249bae --- /dev/null +++ b/app/src/main/res/drawable/ic_home_filter.xml @@ -0,0 +1,7 @@ + + + + + diff --git a/app/src/main/res/drawable/ic_home_menu_lines.xml b/app/src/main/res/drawable/ic_home_menu_lines.xml new file mode 100644 index 0000000..3589032 --- /dev/null +++ b/app/src/main/res/drawable/ic_home_menu_lines.xml @@ -0,0 +1,11 @@ + + + + + diff --git a/app/src/main/res/drawable/ic_home_menu_messages.xml b/app/src/main/res/drawable/ic_home_menu_messages.xml new file mode 100644 index 0000000..8b83f5a --- /dev/null +++ b/app/src/main/res/drawable/ic_home_menu_messages.xml @@ -0,0 +1,6 @@ + + + + diff --git a/app/src/main/res/drawable/ic_home_menu_person.xml b/app/src/main/res/drawable/ic_home_menu_person.xml new file mode 100644 index 0000000..18ae2ba --- /dev/null +++ b/app/src/main/res/drawable/ic_home_menu_person.xml @@ -0,0 +1,6 @@ + + + + diff --git a/app/src/main/res/drawable/ic_home_menu_pin.xml b/app/src/main/res/drawable/ic_home_menu_pin.xml new file mode 100644 index 0000000..3957615 --- /dev/null +++ b/app/src/main/res/drawable/ic_home_menu_pin.xml @@ -0,0 +1,6 @@ + + + + diff --git a/app/src/main/res/drawable/ic_home_menu_select.xml b/app/src/main/res/drawable/ic_home_menu_select.xml new file mode 100644 index 0000000..f678d8a --- /dev/null +++ b/app/src/main/res/drawable/ic_home_menu_select.xml @@ -0,0 +1,6 @@ + + + + diff --git a/app/src/main/res/drawable/ic_home_menu_spam.xml b/app/src/main/res/drawable/ic_home_menu_spam.xml new file mode 100644 index 0000000..b2cdc85 --- /dev/null +++ b/app/src/main/res/drawable/ic_home_menu_spam.xml @@ -0,0 +1,7 @@ + + + + + diff --git a/app/src/main/res/drawable/ic_home_menu_trash.xml b/app/src/main/res/drawable/ic_home_menu_trash.xml new file mode 100644 index 0000000..4b82fd1 --- /dev/null +++ b/app/src/main/res/drawable/ic_home_menu_trash.xml @@ -0,0 +1,6 @@ + + + + diff --git a/app/src/main/res/drawable/ic_home_menu_unread.xml b/app/src/main/res/drawable/ic_home_menu_unread.xml new file mode 100644 index 0000000..305d68a --- /dev/null +++ b/app/src/main/res/drawable/ic_home_menu_unread.xml @@ -0,0 +1,8 @@ + + + + + diff --git a/app/src/main/res/drawable/ic_home_mic.xml b/app/src/main/res/drawable/ic_home_mic.xml new file mode 100644 index 0000000..1fc686f --- /dev/null +++ b/app/src/main/res/drawable/ic_home_mic.xml @@ -0,0 +1,6 @@ + + + + diff --git a/app/src/main/res/drawable/ic_home_nav_automate.xml b/app/src/main/res/drawable/ic_home_nav_automate.xml new file mode 100644 index 0000000..0895157 --- /dev/null +++ b/app/src/main/res/drawable/ic_home_nav_automate.xml @@ -0,0 +1,12 @@ + + + + + diff --git a/app/src/main/res/drawable/ic_home_nav_calls.xml b/app/src/main/res/drawable/ic_home_nav_calls.xml new file mode 100644 index 0000000..d158834 --- /dev/null +++ b/app/src/main/res/drawable/ic_home_nav_calls.xml @@ -0,0 +1,10 @@ + + + + diff --git a/app/src/main/res/drawable/ic_home_nav_chats.xml b/app/src/main/res/drawable/ic_home_nav_chats.xml new file mode 100644 index 0000000..7a83135 --- /dev/null +++ b/app/src/main/res/drawable/ic_home_nav_chats.xml @@ -0,0 +1,16 @@ + + + + + + + + diff --git a/app/src/main/res/drawable/ic_home_nav_compose.xml b/app/src/main/res/drawable/ic_home_nav_compose.xml new file mode 100644 index 0000000..c0a1dec --- /dev/null +++ b/app/src/main/res/drawable/ic_home_nav_compose.xml @@ -0,0 +1,12 @@ + + + + + diff --git a/app/src/main/res/drawable/ic_home_nav_contacts.xml b/app/src/main/res/drawable/ic_home_nav_contacts.xml new file mode 100644 index 0000000..6f5f46f --- /dev/null +++ b/app/src/main/res/drawable/ic_home_nav_contacts.xml @@ -0,0 +1,11 @@ + + + + + diff --git a/app/src/main/res/drawable/ic_home_nav_messages.xml b/app/src/main/res/drawable/ic_home_nav_messages.xml new file mode 100644 index 0000000..9393ec2 --- /dev/null +++ b/app/src/main/res/drawable/ic_home_nav_messages.xml @@ -0,0 +1,11 @@ + + + + + diff --git a/app/src/main/res/drawable/ic_home_nav_settings.xml b/app/src/main/res/drawable/ic_home_nav_settings.xml new file mode 100644 index 0000000..c615326 --- /dev/null +++ b/app/src/main/res/drawable/ic_home_nav_settings.xml @@ -0,0 +1,10 @@ + + + + diff --git a/app/src/main/res/drawable/ic_home_pinned_remove.xml b/app/src/main/res/drawable/ic_home_pinned_remove.xml new file mode 100644 index 0000000..4d528d5 --- /dev/null +++ b/app/src/main/res/drawable/ic_home_pinned_remove.xml @@ -0,0 +1,10 @@ + + + + diff --git a/app/src/main/res/drawable/ic_home_search_line.xml b/app/src/main/res/drawable/ic_home_search_line.xml new file mode 100644 index 0000000..42b3ec6 --- /dev/null +++ b/app/src/main/res/drawable/ic_home_search_line.xml @@ -0,0 +1,19 @@ + + + + + diff --git a/res/drawable/ic_image_light.xml b/app/src/main/res/drawable/ic_image_light.xml similarity index 100% rename from res/drawable/ic_image_light.xml rename to app/src/main/res/drawable/ic_image_light.xml diff --git a/res/drawable/ic_ime_light.xml b/app/src/main/res/drawable/ic_ime_light.xml similarity index 100% rename from res/drawable/ic_ime_light.xml rename to app/src/main/res/drawable/ic_ime_light.xml diff --git a/res/drawable/ic_info_light.xml b/app/src/main/res/drawable/ic_info_light.xml similarity index 100% rename from res/drawable/ic_info_light.xml rename to app/src/main/res/drawable/ic_info_light.xml diff --git a/res/drawable/ic_launcher_background.xml b/app/src/main/res/drawable/ic_launcher_background.xml similarity index 100% rename from res/drawable/ic_launcher_background.xml rename to app/src/main/res/drawable/ic_launcher_background.xml diff --git a/res/drawable/ic_launcher_foreground.xml b/app/src/main/res/drawable/ic_launcher_foreground.xml similarity index 100% rename from res/drawable/ic_launcher_foreground.xml rename to app/src/main/res/drawable/ic_launcher_foreground.xml diff --git a/res/drawable/ic_launcher_monochrome.xml b/app/src/main/res/drawable/ic_launcher_monochrome.xml similarity index 100% rename from res/drawable/ic_launcher_monochrome.xml rename to app/src/main/res/drawable/ic_launcher_monochrome.xml diff --git a/app/src/main/res/drawable/ic_looply_automate.xml b/app/src/main/res/drawable/ic_looply_automate.xml new file mode 100644 index 0000000..7e78e2c --- /dev/null +++ b/app/src/main/res/drawable/ic_looply_automate.xml @@ -0,0 +1,10 @@ + + + + diff --git a/app/src/main/res/drawable/ic_looply_back.xml b/app/src/main/res/drawable/ic_looply_back.xml new file mode 100644 index 0000000..75c185a --- /dev/null +++ b/app/src/main/res/drawable/ic_looply_back.xml @@ -0,0 +1,14 @@ + + + + + diff --git a/app/src/main/res/drawable/ic_looply_contacts.xml b/app/src/main/res/drawable/ic_looply_contacts.xml new file mode 100644 index 0000000..7f3d591 --- /dev/null +++ b/app/src/main/res/drawable/ic_looply_contacts.xml @@ -0,0 +1,10 @@ + + + + diff --git a/app/src/main/res/drawable/ic_looply_more.xml b/app/src/main/res/drawable/ic_looply_more.xml new file mode 100644 index 0000000..d647977 --- /dev/null +++ b/app/src/main/res/drawable/ic_looply_more.xml @@ -0,0 +1,10 @@ + + + + diff --git a/app/src/main/res/drawable/ic_looply_search.xml b/app/src/main/res/drawable/ic_looply_search.xml new file mode 100644 index 0000000..8846a59 --- /dev/null +++ b/app/src/main/res/drawable/ic_looply_search.xml @@ -0,0 +1,10 @@ + + + + diff --git a/res/drawable/ic_message.xml b/app/src/main/res/drawable/ic_message.xml similarity index 100% rename from res/drawable/ic_message.xml rename to app/src/main/res/drawable/ic_message.xml diff --git a/res/drawable/ic_mp_audio_mic.xml b/app/src/main/res/drawable/ic_mp_audio_mic.xml similarity index 100% rename from res/drawable/ic_mp_audio_mic.xml rename to app/src/main/res/drawable/ic_mp_audio_mic.xml diff --git a/res/drawable/ic_mp_video_small_light.xml b/app/src/main/res/drawable/ic_mp_video_small_light.xml similarity index 100% rename from res/drawable/ic_mp_video_small_light.xml rename to app/src/main/res/drawable/ic_mp_video_small_light.xml diff --git a/res/drawable/ic_numeric_dialpad.xml b/app/src/main/res/drawable/ic_numeric_dialpad.xml similarity index 100% rename from res/drawable/ic_numeric_dialpad.xml rename to app/src/main/res/drawable/ic_numeric_dialpad.xml diff --git a/res/drawable/ic_pause_light.xml b/app/src/main/res/drawable/ic_pause_light.xml similarity index 100% rename from res/drawable/ic_pause_light.xml rename to app/src/main/res/drawable/ic_pause_light.xml diff --git a/res/drawable/ic_people_add_light.xml b/app/src/main/res/drawable/ic_people_add_light.xml similarity index 100% rename from res/drawable/ic_people_add_light.xml rename to app/src/main/res/drawable/ic_people_add_light.xml diff --git a/res/drawable/ic_person_add_light.xml b/app/src/main/res/drawable/ic_person_add_light.xml similarity index 100% rename from res/drawable/ic_person_add_light.xml rename to app/src/main/res/drawable/ic_person_add_light.xml diff --git a/res/drawable/ic_person_light.xml b/app/src/main/res/drawable/ic_person_light.xml similarity index 100% rename from res/drawable/ic_person_light.xml rename to app/src/main/res/drawable/ic_person_light.xml diff --git a/res/drawable/ic_phone_small_light.xml b/app/src/main/res/drawable/ic_phone_small_light.xml similarity index 100% rename from res/drawable/ic_phone_small_light.xml rename to app/src/main/res/drawable/ic_phone_small_light.xml diff --git a/res/drawable/ic_play_light.xml b/app/src/main/res/drawable/ic_play_light.xml similarity index 100% rename from res/drawable/ic_play_light.xml rename to app/src/main/res/drawable/ic_play_light.xml diff --git a/res/drawable/ic_save_light.xml b/app/src/main/res/drawable/ic_save_light.xml similarity index 100% rename from res/drawable/ic_save_light.xml rename to app/src/main/res/drawable/ic_save_light.xml diff --git a/res/drawable/ic_send_light.xml b/app/src/main/res/drawable/ic_send_light.xml similarity index 100% rename from res/drawable/ic_send_light.xml rename to app/src/main/res/drawable/ic_send_light.xml diff --git a/res/drawable/ic_share_light.xml b/app/src/main/res/drawable/ic_share_light.xml similarity index 100% rename from res/drawable/ic_share_light.xml rename to app/src/main/res/drawable/ic_share_light.xml diff --git a/res/drawable/ic_sms_light.xml b/app/src/main/res/drawable/ic_sms_light.xml similarity index 100% rename from res/drawable/ic_sms_light.xml rename to app/src/main/res/drawable/ic_sms_light.xml diff --git a/res/drawable/ic_wear_reply.xml b/app/src/main/res/drawable/ic_wear_reply.xml similarity index 100% rename from res/drawable/ic_wear_reply.xml rename to app/src/main/res/drawable/ic_wear_reply.xml diff --git a/res/drawable/ic_widget_list.xml b/app/src/main/res/drawable/ic_widget_list.xml similarity index 100% rename from res/drawable/ic_widget_list.xml rename to app/src/main/res/drawable/ic_widget_list.xml diff --git a/res/drawable/ic_work_profile.xml b/app/src/main/res/drawable/ic_work_profile.xml similarity index 100% rename from res/drawable/ic_work_profile.xml rename to app/src/main/res/drawable/ic_work_profile.xml diff --git a/app/src/main/res/drawable/looply_bg_avatar_placeholder.xml b/app/src/main/res/drawable/looply_bg_avatar_placeholder.xml new file mode 100644 index 0000000..69409ba --- /dev/null +++ b/app/src/main/res/drawable/looply_bg_avatar_placeholder.xml @@ -0,0 +1,5 @@ + + + + diff --git a/app/src/main/res/drawable/looply_bg_badge.xml b/app/src/main/res/drawable/looply_bg_badge.xml new file mode 100644 index 0000000..2a878ed --- /dev/null +++ b/app/src/main/res/drawable/looply_bg_badge.xml @@ -0,0 +1,5 @@ + + + + diff --git a/app/src/main/res/drawable/looply_bg_bubble_incoming.xml b/app/src/main/res/drawable/looply_bg_bubble_incoming.xml new file mode 100644 index 0000000..ab79f15 --- /dev/null +++ b/app/src/main/res/drawable/looply_bg_bubble_incoming.xml @@ -0,0 +1,10 @@ + + + + + diff --git a/app/src/main/res/drawable/looply_bg_bubble_outgoing.xml b/app/src/main/res/drawable/looply_bg_bubble_outgoing.xml new file mode 100644 index 0000000..9a0afc1 --- /dev/null +++ b/app/src/main/res/drawable/looply_bg_bubble_outgoing.xml @@ -0,0 +1,10 @@ + + + + + diff --git a/app/src/main/res/drawable/looply_bg_button_primary.xml b/app/src/main/res/drawable/looply_bg_button_primary.xml new file mode 100644 index 0000000..cc09bc8 --- /dev/null +++ b/app/src/main/res/drawable/looply_bg_button_primary.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/res/drawable/looply_bg_button_secondary.xml b/app/src/main/res/drawable/looply_bg_button_secondary.xml new file mode 100644 index 0000000..e4e6617 --- /dev/null +++ b/app/src/main/res/drawable/looply_bg_button_secondary.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/res/drawable/looply_bg_card.xml b/app/src/main/res/drawable/looply_bg_card.xml new file mode 100644 index 0000000..e1a202c --- /dev/null +++ b/app/src/main/res/drawable/looply_bg_card.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/res/drawable/looply_bg_chip_active.xml b/app/src/main/res/drawable/looply_bg_chip_active.xml new file mode 100644 index 0000000..cc09bc8 --- /dev/null +++ b/app/src/main/res/drawable/looply_bg_chip_active.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/res/drawable/looply_bg_chip_inactive.xml b/app/src/main/res/drawable/looply_bg_chip_inactive.xml new file mode 100644 index 0000000..42e7158 --- /dev/null +++ b/app/src/main/res/drawable/looply_bg_chip_inactive.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/res/drawable/looply_bg_fab.xml b/app/src/main/res/drawable/looply_bg_fab.xml new file mode 100644 index 0000000..adc4f00 --- /dev/null +++ b/app/src/main/res/drawable/looply_bg_fab.xml @@ -0,0 +1,5 @@ + + + + diff --git a/app/src/main/res/drawable/looply_bg_fab_square.xml b/app/src/main/res/drawable/looply_bg_fab_square.xml new file mode 100644 index 0000000..9fcd66b --- /dev/null +++ b/app/src/main/res/drawable/looply_bg_fab_square.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/res/drawable/looply_bg_input.xml b/app/src/main/res/drawable/looply_bg_input.xml new file mode 100644 index 0000000..cdb43e8 --- /dev/null +++ b/app/src/main/res/drawable/looply_bg_input.xml @@ -0,0 +1,9 @@ + + + + + + diff --git a/app/src/main/res/drawable/looply_bg_list_card.xml b/app/src/main/res/drawable/looply_bg_list_card.xml new file mode 100644 index 0000000..e1a202c --- /dev/null +++ b/app/src/main/res/drawable/looply_bg_list_card.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/res/drawable/looply_bg_list_sheet.xml b/app/src/main/res/drawable/looply_bg_list_sheet.xml new file mode 100644 index 0000000..3846574 --- /dev/null +++ b/app/src/main/res/drawable/looply_bg_list_sheet.xml @@ -0,0 +1,8 @@ + + + + + diff --git a/app/src/main/res/drawable/looply_bg_nav_active_circle.xml b/app/src/main/res/drawable/looply_bg_nav_active_circle.xml new file mode 100644 index 0000000..adc4f00 --- /dev/null +++ b/app/src/main/res/drawable/looply_bg_nav_active_circle.xml @@ -0,0 +1,5 @@ + + + + diff --git a/app/src/main/res/drawable/looply_bg_nav_active_pill.xml b/app/src/main/res/drawable/looply_bg_nav_active_pill.xml new file mode 100644 index 0000000..cc09bc8 --- /dev/null +++ b/app/src/main/res/drawable/looply_bg_nav_active_pill.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/res/drawable/looply_bg_nav_floating_pill.xml b/app/src/main/res/drawable/looply_bg_nav_floating_pill.xml new file mode 100644 index 0000000..8c37cc6 --- /dev/null +++ b/app/src/main/res/drawable/looply_bg_nav_floating_pill.xml @@ -0,0 +1,9 @@ + + + + + + diff --git a/app/src/main/res/drawable/looply_bg_online_dot.xml b/app/src/main/res/drawable/looply_bg_online_dot.xml new file mode 100644 index 0000000..57affc7 --- /dev/null +++ b/app/src/main/res/drawable/looply_bg_online_dot.xml @@ -0,0 +1,8 @@ + + + + + diff --git a/app/src/main/res/drawable/looply_bg_search.xml b/app/src/main/res/drawable/looply_bg_search.xml new file mode 100644 index 0000000..a2cf68a --- /dev/null +++ b/app/src/main/res/drawable/looply_bg_search.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/res/drawable/mediapicker_tab_button_background.xml b/app/src/main/res/drawable/mediapicker_tab_button_background.xml similarity index 100% rename from res/drawable/mediapicker_tab_button_background.xml rename to app/src/main/res/drawable/mediapicker_tab_button_background.xml diff --git a/res/drawable/message_bubble_incoming_no_arrow.xml b/app/src/main/res/drawable/message_bubble_incoming_no_arrow.xml similarity index 82% rename from res/drawable/message_bubble_incoming_no_arrow.xml rename to app/src/main/res/drawable/message_bubble_incoming_no_arrow.xml index 050da48..496743d 100644 --- a/res/drawable/message_bubble_incoming_no_arrow.xml +++ b/app/src/main/res/drawable/message_bubble_incoming_no_arrow.xml @@ -16,5 +16,9 @@ --> - + diff --git a/res/drawable/message_bubble_outgoing_no_arrow.xml b/app/src/main/res/drawable/message_bubble_outgoing_no_arrow.xml similarity index 82% rename from res/drawable/message_bubble_outgoing_no_arrow.xml rename to app/src/main/res/drawable/message_bubble_outgoing_no_arrow.xml index 050da48..0be7049 100644 --- a/res/drawable/message_bubble_outgoing_no_arrow.xml +++ b/app/src/main/res/drawable/message_bubble_outgoing_no_arrow.xml @@ -16,5 +16,9 @@ --> - + diff --git a/res/drawable/msg_bubble_input_rounded.xml b/app/src/main/res/drawable/msg_bubble_input_rounded.xml similarity index 100% rename from res/drawable/msg_bubble_input_rounded.xml rename to app/src/main/res/drawable/msg_bubble_input_rounded.xml diff --git a/res/drawable/send_arrow_background.xml b/app/src/main/res/drawable/send_arrow_background.xml similarity index 100% rename from res/drawable/send_arrow_background.xml rename to app/src/main/res/drawable/send_arrow_background.xml diff --git a/res/drawable/sim_selector_background_gradient.xml b/app/src/main/res/drawable/sim_selector_background_gradient.xml similarity index 100% rename from res/drawable/sim_selector_background_gradient.xml rename to app/src/main/res/drawable/sim_selector_background_gradient.xml diff --git a/res/drawable/subject_editor_bubble.xml b/app/src/main/res/drawable/subject_editor_bubble.xml similarity index 100% rename from res/drawable/subject_editor_bubble.xml rename to app/src/main/res/drawable/subject_editor_bubble.xml diff --git a/res/drawable/transparent_button_background.xml b/app/src/main/res/drawable/transparent_button_background.xml similarity index 100% rename from res/drawable/transparent_button_background.xml rename to app/src/main/res/drawable/transparent_button_background.xml diff --git a/res/drawable/widget_bottom_background.xml b/app/src/main/res/drawable/widget_bottom_background.xml similarity index 100% rename from res/drawable/widget_bottom_background.xml rename to app/src/main/res/drawable/widget_bottom_background.xml diff --git a/res/drawable/widget_item_background.xml b/app/src/main/res/drawable/widget_item_background.xml similarity index 100% rename from res/drawable/widget_item_background.xml rename to app/src/main/res/drawable/widget_item_background.xml diff --git a/res/drawable/widget_top_background.xml b/app/src/main/res/drawable/widget_top_background.xml similarity index 100% rename from res/drawable/widget_top_background.xml rename to app/src/main/res/drawable/widget_top_background.xml diff --git a/res/layout/action_bar_conversation_name.xml b/app/src/main/res/layout/action_bar_conversation_name.xml similarity index 100% rename from res/layout/action_bar_conversation_name.xml rename to app/src/main/res/layout/action_bar_conversation_name.xml diff --git a/res/layout/add_contacts_confirmation_dialog_body.xml b/app/src/main/res/layout/add_contacts_confirmation_dialog_body.xml similarity index 100% rename from res/layout/add_contacts_confirmation_dialog_body.xml rename to app/src/main/res/layout/add_contacts_confirmation_dialog_body.xml diff --git a/res/layout/all_contacts_list_view.xml b/app/src/main/res/layout/all_contacts_list_view.xml similarity index 100% rename from res/layout/all_contacts_list_view.xml rename to app/src/main/res/layout/all_contacts_list_view.xml diff --git a/res/layout/attachment_chooser_activity.xml b/app/src/main/res/layout/attachment_chooser_activity.xml similarity index 100% rename from res/layout/attachment_chooser_activity.xml rename to app/src/main/res/layout/attachment_chooser_activity.xml diff --git a/res/layout/attachment_chooser_audio.xml b/app/src/main/res/layout/attachment_chooser_audio.xml similarity index 100% rename from res/layout/attachment_chooser_audio.xml rename to app/src/main/res/layout/attachment_chooser_audio.xml diff --git a/res/layout/attachment_chooser_fragment.xml b/app/src/main/res/layout/attachment_chooser_fragment.xml similarity index 100% rename from res/layout/attachment_chooser_fragment.xml rename to app/src/main/res/layout/attachment_chooser_fragment.xml diff --git a/res/layout/attachment_chooser_image.xml b/app/src/main/res/layout/attachment_chooser_image.xml similarity index 100% rename from res/layout/attachment_chooser_image.xml rename to app/src/main/res/layout/attachment_chooser_image.xml diff --git a/res/layout/attachment_chooser_vcard.xml b/app/src/main/res/layout/attachment_chooser_vcard.xml similarity index 100% rename from res/layout/attachment_chooser_vcard.xml rename to app/src/main/res/layout/attachment_chooser_vcard.xml diff --git a/res/layout/attachment_chooser_video.xml b/app/src/main/res/layout/attachment_chooser_video.xml similarity index 100% rename from res/layout/attachment_chooser_video.xml rename to app/src/main/res/layout/attachment_chooser_video.xml diff --git a/res/layout/attachment_grid_item_view.xml b/app/src/main/res/layout/attachment_grid_item_view.xml similarity index 100% rename from res/layout/attachment_grid_item_view.xml rename to app/src/main/res/layout/attachment_grid_item_view.xml diff --git a/res/layout/attachment_more_text_view.xml b/app/src/main/res/layout/attachment_more_text_view.xml similarity index 100% rename from res/layout/attachment_more_text_view.xml rename to app/src/main/res/layout/attachment_more_text_view.xml diff --git a/res/layout/attachment_multiple_audio.xml b/app/src/main/res/layout/attachment_multiple_audio.xml similarity index 100% rename from res/layout/attachment_multiple_audio.xml rename to app/src/main/res/layout/attachment_multiple_audio.xml diff --git a/res/layout/attachment_multiple_image.xml b/app/src/main/res/layout/attachment_multiple_image.xml similarity index 100% rename from res/layout/attachment_multiple_image.xml rename to app/src/main/res/layout/attachment_multiple_image.xml diff --git a/res/layout/attachment_multiple_vcard.xml b/app/src/main/res/layout/attachment_multiple_vcard.xml similarity index 100% rename from res/layout/attachment_multiple_vcard.xml rename to app/src/main/res/layout/attachment_multiple_vcard.xml diff --git a/res/layout/attachment_multiple_video.xml b/app/src/main/res/layout/attachment_multiple_video.xml similarity index 100% rename from res/layout/attachment_multiple_video.xml rename to app/src/main/res/layout/attachment_multiple_video.xml diff --git a/res/layout/attachment_pending_item.xml b/app/src/main/res/layout/attachment_pending_item.xml similarity index 100% rename from res/layout/attachment_pending_item.xml rename to app/src/main/res/layout/attachment_pending_item.xml diff --git a/res/layout/attachment_preview.xml b/app/src/main/res/layout/attachment_preview.xml similarity index 100% rename from res/layout/attachment_preview.xml rename to app/src/main/res/layout/attachment_preview.xml diff --git a/res/layout/attachment_single_audio.xml b/app/src/main/res/layout/attachment_single_audio.xml similarity index 100% rename from res/layout/attachment_single_audio.xml rename to app/src/main/res/layout/attachment_single_audio.xml diff --git a/res/layout/attachment_single_image.xml b/app/src/main/res/layout/attachment_single_image.xml similarity index 100% rename from res/layout/attachment_single_image.xml rename to app/src/main/res/layout/attachment_single_image.xml diff --git a/res/layout/attachment_single_vcard.xml b/app/src/main/res/layout/attachment_single_vcard.xml similarity index 100% rename from res/layout/attachment_single_vcard.xml rename to app/src/main/res/layout/attachment_single_vcard.xml diff --git a/res/layout/attachment_single_video.xml b/app/src/main/res/layout/attachment_single_video.xml similarity index 100% rename from res/layout/attachment_single_video.xml rename to app/src/main/res/layout/attachment_single_video.xml diff --git a/res/layout/audio_attachment_view.xml b/app/src/main/res/layout/audio_attachment_view.xml similarity index 100% rename from res/layout/audio_attachment_view.xml rename to app/src/main/res/layout/audio_attachment_view.xml diff --git a/res/layout/blocked_participant_list_item_view.xml b/app/src/main/res/layout/blocked_participant_list_item_view.xml similarity index 100% rename from res/layout/blocked_participant_list_item_view.xml rename to app/src/main/res/layout/blocked_participant_list_item_view.xml diff --git a/res/layout/blocked_participants_activity.xml b/app/src/main/res/layout/blocked_participants_activity.xml similarity index 100% rename from res/layout/blocked_participants_activity.xml rename to app/src/main/res/layout/blocked_participants_activity.xml diff --git a/res/layout/blocked_participants_fragment.xml b/app/src/main/res/layout/blocked_participants_fragment.xml similarity index 100% rename from res/layout/blocked_participants_fragment.xml rename to app/src/main/res/layout/blocked_participants_fragment.xml diff --git a/res/layout/chips_alternates_dropdown_item.xml b/app/src/main/res/layout/chips_alternates_dropdown_item.xml similarity index 100% rename from res/layout/chips_alternates_dropdown_item.xml rename to app/src/main/res/layout/chips_alternates_dropdown_item.xml diff --git a/res/layout/compose_message_view.xml b/app/src/main/res/layout/compose_message_view.xml similarity index 100% rename from res/layout/compose_message_view.xml rename to app/src/main/res/layout/compose_message_view.xml diff --git a/res/layout/contact_list_item_view.xml b/app/src/main/res/layout/contact_list_item_view.xml similarity index 61% rename from res/layout/contact_list_item_view.xml rename to app/src/main/res/layout/contact_list_item_view.xml index b321a9a..db2009b 100644 --- a/res/layout/contact_list_item_view.xml +++ b/app/src/main/res/layout/contact_list_item_view.xml @@ -18,20 +18,29 @@ + android:layout_marginStart="@dimen/looply_space_md" + android:layout_marginEnd="@dimen/looply_space_md" + android:layout_marginBottom="@dimen/looply_space_sm" + android:background="@drawable/looply_bg_list_card" + android:elevation="2dp" + android:gravity="center_vertical" + android:minHeight="@dimen/looply_list_item_min_height" + android:paddingStart="@dimen/looply_space_md" + android:paddingEnd="@dimen/looply_space_md" + android:paddingTop="@dimen/looply_space_md" + android:paddingBottom="@dimen/looply_space_md" + android:foreground="?android:attr/selectableItemBackground"> + android:contentDescription="@null"/> + android:layout_weight="1" + android:layout_gravity="center_vertical" + android:layout_marginStart="@dimen/looply_space_md" + android:layout_marginEnd="@dimen/looply_space_sm"> - + + android:maxLines="1" + android:singleLine="true" + android:textSize="@dimen/looply_text_body" + android:textStyle="bold" /> - + android:layout_height="wrap_content" + android:layout_marginTop="@dimen/looply_space_xs" + android:gravity="center_vertical"> + android:maxLines="1" + android:singleLine="true" /> + android:layout_marginStart="@dimen/looply_space_sm" + android:textColor="@color/looply_primary" /> diff --git a/app/src/main/res/layout/contact_picker_fragment.xml b/app/src/main/res/layout/contact_picker_fragment.xml new file mode 100644 index 0000000..114e09a --- /dev/null +++ b/app/src/main/res/layout/contact_picker_fragment.xml @@ -0,0 +1,108 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/layout/conversation_activity.xml b/app/src/main/res/layout/conversation_activity.xml similarity index 100% rename from res/layout/conversation_activity.xml rename to app/src/main/res/layout/conversation_activity.xml diff --git a/res/layout/conversation_fragment.xml b/app/src/main/res/layout/conversation_fragment.xml similarity index 100% rename from res/layout/conversation_fragment.xml rename to app/src/main/res/layout/conversation_fragment.xml diff --git a/app/src/main/res/layout/conversation_list_fragment.xml b/app/src/main/res/layout/conversation_list_fragment.xml new file mode 100644 index 0000000..bc36ab2 --- /dev/null +++ b/app/src/main/res/layout/conversation_list_fragment.xml @@ -0,0 +1,401 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/conversation_list_item_view.xml b/app/src/main/res/layout/conversation_list_item_view.xml new file mode 100644 index 0000000..3f48c67 --- /dev/null +++ b/app/src/main/res/layout/conversation_list_item_view.xml @@ -0,0 +1,302 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/layout/conversation_message_view.xml b/app/src/main/res/layout/conversation_message_view.xml similarity index 100% rename from res/layout/conversation_message_view.xml rename to app/src/main/res/layout/conversation_message_view.xml diff --git a/res/layout/copy_contact_dialog_view.xml b/app/src/main/res/layout/copy_contact_dialog_view.xml similarity index 100% rename from res/layout/copy_contact_dialog_view.xml rename to app/src/main/res/layout/copy_contact_dialog_view.xml diff --git a/res/layout/custom_header_view_pager.xml b/app/src/main/res/layout/custom_header_view_pager.xml similarity index 100% rename from res/layout/custom_header_view_pager.xml rename to app/src/main/res/layout/custom_header_view_pager.xml diff --git a/res/layout/enter_phone_number_view.xml b/app/src/main/res/layout/enter_phone_number_view.xml similarity index 100% rename from res/layout/enter_phone_number_view.xml rename to app/src/main/res/layout/enter_phone_number_view.xml diff --git a/res/layout/fastscroll_preview.xml b/app/src/main/res/layout/fastscroll_preview.xml similarity index 100% rename from res/layout/fastscroll_preview.xml rename to app/src/main/res/layout/fastscroll_preview.xml diff --git a/res/layout/fastscroll_thumb.xml b/app/src/main/res/layout/fastscroll_thumb.xml similarity index 100% rename from res/layout/fastscroll_thumb.xml rename to app/src/main/res/layout/fastscroll_thumb.xml diff --git a/res/layout/fastscroll_track.xml b/app/src/main/res/layout/fastscroll_track.xml similarity index 100% rename from res/layout/fastscroll_track.xml rename to app/src/main/res/layout/fastscroll_track.xml diff --git a/res/layout/frequent_contacts_list_view.xml b/app/src/main/res/layout/frequent_contacts_list_view.xml similarity index 100% rename from res/layout/frequent_contacts_list_view.xml rename to app/src/main/res/layout/frequent_contacts_list_view.xml diff --git a/res/layout/group_mms_setting_dialog.xml b/app/src/main/res/layout/group_mms_setting_dialog.xml similarity index 100% rename from res/layout/group_mms_setting_dialog.xml rename to app/src/main/res/layout/group_mms_setting_dialog.xml diff --git a/app/src/main/res/layout/home_bottom_nav_tab_item.xml b/app/src/main/res/layout/home_bottom_nav_tab_item.xml new file mode 100644 index 0000000..2723f1f --- /dev/null +++ b/app/src/main/res/layout/home_bottom_nav_tab_item.xml @@ -0,0 +1,39 @@ + + + + + + + + + + diff --git a/app/src/main/res/layout/home_contacts_fragment.xml b/app/src/main/res/layout/home_contacts_fragment.xml new file mode 100644 index 0000000..80b9170 --- /dev/null +++ b/app/src/main/res/layout/home_contacts_fragment.xml @@ -0,0 +1,180 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/home_contacts_list_item.xml b/app/src/main/res/layout/home_contacts_list_item.xml new file mode 100644 index 0000000..4d86ea8 --- /dev/null +++ b/app/src/main/res/layout/home_contacts_list_item.xml @@ -0,0 +1,74 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/home_pinned_item.xml b/app/src/main/res/layout/home_pinned_item.xml new file mode 100644 index 0000000..f4b032a --- /dev/null +++ b/app/src/main/res/layout/home_pinned_item.xml @@ -0,0 +1,130 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/home_pinned_strip.xml b/app/src/main/res/layout/home_pinned_strip.xml new file mode 100644 index 0000000..67af1d0 --- /dev/null +++ b/app/src/main/res/layout/home_pinned_strip.xml @@ -0,0 +1,21 @@ + + + + + diff --git a/app/src/main/res/layout/home_popover_edit.xml b/app/src/main/res/layout/home_popover_edit.xml new file mode 100644 index 0000000..9565907 --- /dev/null +++ b/app/src/main/res/layout/home_popover_edit.xml @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/home_popover_filter.xml b/app/src/main/res/layout/home_popover_filter.xml new file mode 100644 index 0000000..c29238b --- /dev/null +++ b/app/src/main/res/layout/home_popover_filter.xml @@ -0,0 +1,228 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/layout/license_activity.xml b/app/src/main/res/layout/license_activity.xml similarity index 100% rename from res/layout/license_activity.xml rename to app/src/main/res/layout/license_activity.xml diff --git a/res/layout/list_empty_view.xml b/app/src/main/res/layout/list_empty_view.xml similarity index 100% rename from res/layout/list_empty_view.xml rename to app/src/main/res/layout/list_empty_view.xml diff --git a/app/src/main/res/layout/looply_bottom_nav.xml b/app/src/main/res/layout/looply_bottom_nav.xml new file mode 100644 index 0000000..069f33a --- /dev/null +++ b/app/src/main/res/layout/looply_bottom_nav.xml @@ -0,0 +1,110 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/looply_button_primary.xml b/app/src/main/res/layout/looply_button_primary.xml new file mode 100644 index 0000000..f96869b --- /dev/null +++ b/app/src/main/res/layout/looply_button_primary.xml @@ -0,0 +1,11 @@ + + + diff --git a/app/src/main/res/layout/looply_chat_list_item.xml b/app/src/main/res/layout/looply_chat_list_item.xml new file mode 100644 index 0000000..0ce79cb --- /dev/null +++ b/app/src/main/res/layout/looply_chat_list_item.xml @@ -0,0 +1,96 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/looply_components_preview.xml b/app/src/main/res/layout/looply_components_preview.xml new file mode 100644 index 0000000..2b1f139 --- /dev/null +++ b/app/src/main/res/layout/looply_components_preview.xml @@ -0,0 +1,191 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/looply_compose_bar.xml b/app/src/main/res/layout/looply_compose_bar.xml new file mode 100644 index 0000000..7b54aa9 --- /dev/null +++ b/app/src/main/res/layout/looply_compose_bar.xml @@ -0,0 +1,33 @@ + + + + + + + + diff --git a/app/src/main/res/layout/looply_filter_chips.xml b/app/src/main/res/layout/looply_filter_chips.xml new file mode 100644 index 0000000..5f467e1 --- /dev/null +++ b/app/src/main/res/layout/looply_filter_chips.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/looply_message_bubbles.xml b/app/src/main/res/layout/looply_message_bubbles.xml new file mode 100644 index 0000000..e0e58bb --- /dev/null +++ b/app/src/main/res/layout/looply_message_bubbles.xml @@ -0,0 +1,27 @@ + + + + + + + + diff --git a/app/src/main/res/layout/looply_search_bar.xml b/app/src/main/res/layout/looply_search_bar.xml new file mode 100644 index 0000000..a759d78 --- /dev/null +++ b/app/src/main/res/layout/looply_search_bar.xml @@ -0,0 +1,31 @@ + + + + + + + + diff --git a/res/layout/mediapicker_audio_chooser.xml b/app/src/main/res/layout/mediapicker_audio_chooser.xml similarity index 100% rename from res/layout/mediapicker_audio_chooser.xml rename to app/src/main/res/layout/mediapicker_audio_chooser.xml diff --git a/res/layout/mediapicker_camera_chooser.xml b/app/src/main/res/layout/mediapicker_camera_chooser.xml similarity index 100% rename from res/layout/mediapicker_camera_chooser.xml rename to app/src/main/res/layout/mediapicker_camera_chooser.xml diff --git a/res/layout/mediapicker_contact_chooser.xml b/app/src/main/res/layout/mediapicker_contact_chooser.xml similarity index 100% rename from res/layout/mediapicker_contact_chooser.xml rename to app/src/main/res/layout/mediapicker_contact_chooser.xml diff --git a/res/layout/mediapicker_fragment.xml b/app/src/main/res/layout/mediapicker_fragment.xml similarity index 100% rename from res/layout/mediapicker_fragment.xml rename to app/src/main/res/layout/mediapicker_fragment.xml diff --git a/res/layout/mediapicker_gallery_chooser.xml b/app/src/main/res/layout/mediapicker_gallery_chooser.xml similarity index 100% rename from res/layout/mediapicker_gallery_chooser.xml rename to app/src/main/res/layout/mediapicker_gallery_chooser.xml diff --git a/res/layout/mediapicker_tab_button.xml b/app/src/main/res/layout/mediapicker_tab_button.xml similarity index 100% rename from res/layout/mediapicker_tab_button.xml rename to app/src/main/res/layout/mediapicker_tab_button.xml diff --git a/res/layout/message_audio_attachment.xml b/app/src/main/res/layout/message_audio_attachment.xml similarity index 100% rename from res/layout/message_audio_attachment.xml rename to app/src/main/res/layout/message_audio_attachment.xml diff --git a/res/layout/message_vcard_attachment.xml b/app/src/main/res/layout/message_vcard_attachment.xml similarity index 100% rename from res/layout/message_vcard_attachment.xml rename to app/src/main/res/layout/message_vcard_attachment.xml diff --git a/res/layout/message_video_attachment.xml b/app/src/main/res/layout/message_video_attachment.xml similarity index 100% rename from res/layout/message_video_attachment.xml rename to app/src/main/res/layout/message_video_attachment.xml diff --git a/res/layout/people_and_options_activity.xml b/app/src/main/res/layout/people_and_options_activity.xml similarity index 100% rename from res/layout/people_and_options_activity.xml rename to app/src/main/res/layout/people_and_options_activity.xml diff --git a/res/layout/people_and_options_fragment.xml b/app/src/main/res/layout/people_and_options_fragment.xml similarity index 100% rename from res/layout/people_and_options_fragment.xml rename to app/src/main/res/layout/people_and_options_fragment.xml diff --git a/res/layout/people_and_options_section_header.xml b/app/src/main/res/layout/people_and_options_section_header.xml similarity index 100% rename from res/layout/people_and_options_section_header.xml rename to app/src/main/res/layout/people_and_options_section_header.xml diff --git a/res/layout/people_list_item_view.xml b/app/src/main/res/layout/people_list_item_view.xml similarity index 100% rename from res/layout/people_list_item_view.xml rename to app/src/main/res/layout/people_list_item_view.xml diff --git a/res/layout/people_options_item_view.xml b/app/src/main/res/layout/people_options_item_view.xml similarity index 100% rename from res/layout/people_options_item_view.xml rename to app/src/main/res/layout/people_options_item_view.xml diff --git a/res/layout/permission_check_activity.xml b/app/src/main/res/layout/permission_check_activity.xml similarity index 100% rename from res/layout/permission_check_activity.xml rename to app/src/main/res/layout/permission_check_activity.xml diff --git a/res/layout/person_item_view.xml b/app/src/main/res/layout/person_item_view.xml similarity index 100% rename from res/layout/person_item_view.xml rename to app/src/main/res/layout/person_item_view.xml diff --git a/res/layout/preference_material_switch.xml b/app/src/main/res/layout/preference_material_switch.xml similarity index 100% rename from res/layout/preference_material_switch.xml rename to app/src/main/res/layout/preference_material_switch.xml diff --git a/res/layout/settings_fragment.xml b/app/src/main/res/layout/settings_fragment.xml similarity index 100% rename from res/layout/settings_fragment.xml rename to app/src/main/res/layout/settings_fragment.xml diff --git a/res/layout/settings_item_view.xml b/app/src/main/res/layout/settings_item_view.xml similarity index 100% rename from res/layout/settings_item_view.xml rename to app/src/main/res/layout/settings_item_view.xml diff --git a/res/layout/share_intent_conversation_list_view.xml b/app/src/main/res/layout/share_intent_conversation_list_view.xml similarity index 100% rename from res/layout/share_intent_conversation_list_view.xml rename to app/src/main/res/layout/share_intent_conversation_list_view.xml diff --git a/res/layout/sim_selector_item_view.xml b/app/src/main/res/layout/sim_selector_item_view.xml similarity index 100% rename from res/layout/sim_selector_item_view.xml rename to app/src/main/res/layout/sim_selector_item_view.xml diff --git a/res/layout/sim_selector_view.xml b/app/src/main/res/layout/sim_selector_view.xml similarity index 100% rename from res/layout/sim_selector_view.xml rename to app/src/main/res/layout/sim_selector_view.xml diff --git a/res/layout/snack_bar.xml b/app/src/main/res/layout/snack_bar.xml similarity index 100% rename from res/layout/snack_bar.xml rename to app/src/main/res/layout/snack_bar.xml diff --git a/res/layout/vcard_detail_activity.xml b/app/src/main/res/layout/vcard_detail_activity.xml similarity index 100% rename from res/layout/vcard_detail_activity.xml rename to app/src/main/res/layout/vcard_detail_activity.xml diff --git a/res/layout/vcard_detail_fragment.xml b/app/src/main/res/layout/vcard_detail_fragment.xml similarity index 100% rename from res/layout/vcard_detail_fragment.xml rename to app/src/main/res/layout/vcard_detail_fragment.xml diff --git a/res/layout/video_thumbnail_view.xml b/app/src/main/res/layout/video_thumbnail_view.xml similarity index 100% rename from res/layout/video_thumbnail_view.xml rename to app/src/main/res/layout/video_thumbnail_view.xml diff --git a/res/layout/widget_conversation.xml b/app/src/main/res/layout/widget_conversation.xml similarity index 100% rename from res/layout/widget_conversation.xml rename to app/src/main/res/layout/widget_conversation.xml diff --git a/res/layout/widget_conversation_list.xml b/app/src/main/res/layout/widget_conversation_list.xml similarity index 100% rename from res/layout/widget_conversation_list.xml rename to app/src/main/res/layout/widget_conversation_list.xml diff --git a/res/layout/widget_conversation_list_item.xml b/app/src/main/res/layout/widget_conversation_list_item.xml similarity index 100% rename from res/layout/widget_conversation_list_item.xml rename to app/src/main/res/layout/widget_conversation_list_item.xml diff --git a/res/layout/widget_loading.xml b/app/src/main/res/layout/widget_loading.xml similarity index 100% rename from res/layout/widget_loading.xml rename to app/src/main/res/layout/widget_loading.xml diff --git a/res/layout/widget_message_item_incoming.xml b/app/src/main/res/layout/widget_message_item_incoming.xml similarity index 100% rename from res/layout/widget_message_item_incoming.xml rename to app/src/main/res/layout/widget_message_item_incoming.xml diff --git a/res/layout/widget_message_item_outgoing.xml b/app/src/main/res/layout/widget_message_item_outgoing.xml similarity index 100% rename from res/layout/widget_message_item_outgoing.xml rename to app/src/main/res/layout/widget_message_item_outgoing.xml diff --git a/res/layout/widget_missing_permission.xml b/app/src/main/res/layout/widget_missing_permission.xml similarity index 100% rename from res/layout/widget_missing_permission.xml rename to app/src/main/res/layout/widget_missing_permission.xml diff --git a/res/layout/work_directory_header.xml b/app/src/main/res/layout/work_directory_header.xml similarity index 100% rename from res/layout/work_directory_header.xml rename to app/src/main/res/layout/work_directory_header.xml diff --git a/res/menu/attachment_chooser_menu.xml b/app/src/main/res/menu/attachment_chooser_menu.xml similarity index 100% rename from res/menu/attachment_chooser_menu.xml rename to app/src/main/res/menu/attachment_chooser_menu.xml diff --git a/res/menu/compose_menu.xml b/app/src/main/res/menu/compose_menu.xml similarity index 100% rename from res/menu/compose_menu.xml rename to app/src/main/res/menu/compose_menu.xml diff --git a/res/menu/conversation_fragment_select_menu.xml b/app/src/main/res/menu/conversation_fragment_select_menu.xml similarity index 100% rename from res/menu/conversation_fragment_select_menu.xml rename to app/src/main/res/menu/conversation_fragment_select_menu.xml diff --git a/res/menu/conversation_list_fragment_menu.xml b/app/src/main/res/menu/conversation_list_fragment_menu.xml similarity index 100% rename from res/menu/conversation_list_fragment_menu.xml rename to app/src/main/res/menu/conversation_list_fragment_menu.xml diff --git a/res/menu/conversation_list_fragment_select_menu.xml b/app/src/main/res/menu/conversation_list_fragment_select_menu.xml similarity index 100% rename from res/menu/conversation_list_fragment_select_menu.xml rename to app/src/main/res/menu/conversation_list_fragment_select_menu.xml diff --git a/res/menu/conversation_menu.xml b/app/src/main/res/menu/conversation_menu.xml similarity index 100% rename from res/menu/conversation_menu.xml rename to app/src/main/res/menu/conversation_menu.xml diff --git a/res/menu/photo_view_menu.xml b/app/src/main/res/menu/photo_view_menu.xml similarity index 100% rename from res/menu/photo_view_menu.xml rename to app/src/main/res/menu/photo_view_menu.xml diff --git a/res/menu/settings_menu.xml b/app/src/main/res/menu/settings_menu.xml similarity index 100% rename from res/menu/settings_menu.xml rename to app/src/main/res/menu/settings_menu.xml diff --git a/res/menu/vcard_detail_fragment_menu.xml b/app/src/main/res/menu/vcard_detail_fragment_menu.xml similarity index 100% rename from res/menu/vcard_detail_fragment_menu.xml rename to app/src/main/res/menu/vcard_detail_fragment_menu.xml diff --git a/res/mipmap-anydpi/ic_launcher.xml b/app/src/main/res/mipmap-anydpi/ic_launcher.xml similarity index 100% rename from res/mipmap-anydpi/ic_launcher.xml rename to app/src/main/res/mipmap-anydpi/ic_launcher.xml diff --git a/res/raw/audio_end.wav b/app/src/main/res/raw/audio_end.wav similarity index 100% rename from res/raw/audio_end.wav rename to app/src/main/res/raw/audio_end.wav diff --git a/res/raw/audio_initiate.wav b/app/src/main/res/raw/audio_initiate.wav similarity index 100% rename from res/raw/audio_initiate.wav rename to app/src/main/res/raw/audio_initiate.wav diff --git a/res/raw/message_failure.wav b/app/src/main/res/raw/message_failure.wav similarity index 100% rename from res/raw/message_failure.wav rename to app/src/main/res/raw/message_failure.wav diff --git a/res/raw/message_sent.wav b/app/src/main/res/raw/message_sent.wav similarity index 100% rename from res/raw/message_sent.wav rename to app/src/main/res/raw/message_sent.wav diff --git a/res/values-af/arrays.xml b/app/src/main/res/values-af/arrays.xml similarity index 100% rename from res/values-af/arrays.xml rename to app/src/main/res/values-af/arrays.xml diff --git a/res/values-af/cm_strings.xml b/app/src/main/res/values-af/cm_strings.xml similarity index 100% rename from res/values-af/cm_strings.xml rename to app/src/main/res/values-af/cm_strings.xml diff --git a/res/values-af/strings.xml b/app/src/main/res/values-af/strings.xml similarity index 100% rename from res/values-af/strings.xml rename to app/src/main/res/values-af/strings.xml diff --git a/res/values-am/arrays.xml b/app/src/main/res/values-am/arrays.xml similarity index 100% rename from res/values-am/arrays.xml rename to app/src/main/res/values-am/arrays.xml diff --git a/res/values-am/strings.xml b/app/src/main/res/values-am/strings.xml similarity index 100% rename from res/values-am/strings.xml rename to app/src/main/res/values-am/strings.xml diff --git a/res/values-ar/arrays.xml b/app/src/main/res/values-ar/arrays.xml similarity index 100% rename from res/values-ar/arrays.xml rename to app/src/main/res/values-ar/arrays.xml diff --git a/res/values-ar/cm_strings.xml b/app/src/main/res/values-ar/cm_strings.xml similarity index 100% rename from res/values-ar/cm_strings.xml rename to app/src/main/res/values-ar/cm_strings.xml diff --git a/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml similarity index 100% rename from res/values-ar/strings.xml rename to app/src/main/res/values-ar/strings.xml diff --git a/res/values-as/cm_strings.xml b/app/src/main/res/values-as/cm_strings.xml similarity index 100% rename from res/values-as/cm_strings.xml rename to app/src/main/res/values-as/cm_strings.xml diff --git a/res/values-ast-rES/cm_strings.xml b/app/src/main/res/values-ast-rES/cm_strings.xml similarity index 100% rename from res/values-ast-rES/cm_strings.xml rename to app/src/main/res/values-ast-rES/cm_strings.xml diff --git a/res/values-az/arrays.xml b/app/src/main/res/values-az/arrays.xml similarity index 100% rename from res/values-az/arrays.xml rename to app/src/main/res/values-az/arrays.xml diff --git a/res/values-az/cm_strings.xml b/app/src/main/res/values-az/cm_strings.xml similarity index 100% rename from res/values-az/cm_strings.xml rename to app/src/main/res/values-az/cm_strings.xml diff --git a/res/values-az/strings.xml b/app/src/main/res/values-az/strings.xml similarity index 100% rename from res/values-az/strings.xml rename to app/src/main/res/values-az/strings.xml diff --git a/res/values-be/cm_strings.xml b/app/src/main/res/values-be/cm_strings.xml similarity index 100% rename from res/values-be/cm_strings.xml rename to app/src/main/res/values-be/cm_strings.xml diff --git a/res/values-bg/arrays.xml b/app/src/main/res/values-bg/arrays.xml similarity index 100% rename from res/values-bg/arrays.xml rename to app/src/main/res/values-bg/arrays.xml diff --git a/res/values-bg/cm_strings.xml b/app/src/main/res/values-bg/cm_strings.xml similarity index 100% rename from res/values-bg/cm_strings.xml rename to app/src/main/res/values-bg/cm_strings.xml diff --git a/res/values-bg/strings.xml b/app/src/main/res/values-bg/strings.xml similarity index 100% rename from res/values-bg/strings.xml rename to app/src/main/res/values-bg/strings.xml diff --git a/res/values-bn/arrays.xml b/app/src/main/res/values-bn/arrays.xml similarity index 100% rename from res/values-bn/arrays.xml rename to app/src/main/res/values-bn/arrays.xml diff --git a/res/values-bn/strings.xml b/app/src/main/res/values-bn/strings.xml similarity index 100% rename from res/values-bn/strings.xml rename to app/src/main/res/values-bn/strings.xml diff --git a/res/values-bs/cm_strings.xml b/app/src/main/res/values-bs/cm_strings.xml similarity index 100% rename from res/values-bs/cm_strings.xml rename to app/src/main/res/values-bs/cm_strings.xml diff --git a/res/values-ca/arrays.xml b/app/src/main/res/values-ca/arrays.xml similarity index 100% rename from res/values-ca/arrays.xml rename to app/src/main/res/values-ca/arrays.xml diff --git a/res/values-ca/cm_strings.xml b/app/src/main/res/values-ca/cm_strings.xml similarity index 100% rename from res/values-ca/cm_strings.xml rename to app/src/main/res/values-ca/cm_strings.xml diff --git a/res/values-ca/strings.xml b/app/src/main/res/values-ca/strings.xml similarity index 100% rename from res/values-ca/strings.xml rename to app/src/main/res/values-ca/strings.xml diff --git a/res/values-ckb/cm_strings.xml b/app/src/main/res/values-ckb/cm_strings.xml similarity index 100% rename from res/values-ckb/cm_strings.xml rename to app/src/main/res/values-ckb/cm_strings.xml diff --git a/res/values-cs/arrays.xml b/app/src/main/res/values-cs/arrays.xml similarity index 100% rename from res/values-cs/arrays.xml rename to app/src/main/res/values-cs/arrays.xml diff --git a/res/values-cs/cm_strings.xml b/app/src/main/res/values-cs/cm_strings.xml similarity index 100% rename from res/values-cs/cm_strings.xml rename to app/src/main/res/values-cs/cm_strings.xml diff --git a/res/values-cs/strings.xml b/app/src/main/res/values-cs/strings.xml similarity index 100% rename from res/values-cs/strings.xml rename to app/src/main/res/values-cs/strings.xml diff --git a/res/values-cy/cm_strings.xml b/app/src/main/res/values-cy/cm_strings.xml similarity index 100% rename from res/values-cy/cm_strings.xml rename to app/src/main/res/values-cy/cm_strings.xml diff --git a/res/values-da/arrays.xml b/app/src/main/res/values-da/arrays.xml similarity index 100% rename from res/values-da/arrays.xml rename to app/src/main/res/values-da/arrays.xml diff --git a/res/values-da/cm_strings.xml b/app/src/main/res/values-da/cm_strings.xml similarity index 100% rename from res/values-da/cm_strings.xml rename to app/src/main/res/values-da/cm_strings.xml diff --git a/res/values-da/strings.xml b/app/src/main/res/values-da/strings.xml similarity index 100% rename from res/values-da/strings.xml rename to app/src/main/res/values-da/strings.xml diff --git a/res/values-de/arrays.xml b/app/src/main/res/values-de/arrays.xml similarity index 100% rename from res/values-de/arrays.xml rename to app/src/main/res/values-de/arrays.xml diff --git a/res/values-de/cm_strings.xml b/app/src/main/res/values-de/cm_strings.xml similarity index 100% rename from res/values-de/cm_strings.xml rename to app/src/main/res/values-de/cm_strings.xml diff --git a/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml similarity index 100% rename from res/values-de/strings.xml rename to app/src/main/res/values-de/strings.xml diff --git a/res/values-el/arrays.xml b/app/src/main/res/values-el/arrays.xml similarity index 100% rename from res/values-el/arrays.xml rename to app/src/main/res/values-el/arrays.xml diff --git a/res/values-el/cm_strings.xml b/app/src/main/res/values-el/cm_strings.xml similarity index 100% rename from res/values-el/cm_strings.xml rename to app/src/main/res/values-el/cm_strings.xml diff --git a/res/values-el/strings.xml b/app/src/main/res/values-el/strings.xml similarity index 100% rename from res/values-el/strings.xml rename to app/src/main/res/values-el/strings.xml diff --git a/res/values-en-rAU/arrays.xml b/app/src/main/res/values-en-rAU/arrays.xml similarity index 100% rename from res/values-en-rAU/arrays.xml rename to app/src/main/res/values-en-rAU/arrays.xml diff --git a/res/values-en-rAU/cm_strings.xml b/app/src/main/res/values-en-rAU/cm_strings.xml similarity index 100% rename from res/values-en-rAU/cm_strings.xml rename to app/src/main/res/values-en-rAU/cm_strings.xml diff --git a/res/values-en-rAU/strings.xml b/app/src/main/res/values-en-rAU/strings.xml similarity index 100% rename from res/values-en-rAU/strings.xml rename to app/src/main/res/values-en-rAU/strings.xml diff --git a/res/values-en-rCA/cm_strings.xml b/app/src/main/res/values-en-rCA/cm_strings.xml similarity index 100% rename from res/values-en-rCA/cm_strings.xml rename to app/src/main/res/values-en-rCA/cm_strings.xml diff --git a/res/values-en-rGB/arrays.xml b/app/src/main/res/values-en-rGB/arrays.xml similarity index 100% rename from res/values-en-rGB/arrays.xml rename to app/src/main/res/values-en-rGB/arrays.xml diff --git a/res/values-en-rGB/cm_strings.xml b/app/src/main/res/values-en-rGB/cm_strings.xml similarity index 100% rename from res/values-en-rGB/cm_strings.xml rename to app/src/main/res/values-en-rGB/cm_strings.xml diff --git a/res/values-en-rGB/strings.xml b/app/src/main/res/values-en-rGB/strings.xml similarity index 100% rename from res/values-en-rGB/strings.xml rename to app/src/main/res/values-en-rGB/strings.xml diff --git a/res/values-en-rIN/arrays.xml b/app/src/main/res/values-en-rIN/arrays.xml similarity index 100% rename from res/values-en-rIN/arrays.xml rename to app/src/main/res/values-en-rIN/arrays.xml diff --git a/res/values-en-rIN/cm_strings.xml b/app/src/main/res/values-en-rIN/cm_strings.xml similarity index 100% rename from res/values-en-rIN/cm_strings.xml rename to app/src/main/res/values-en-rIN/cm_strings.xml diff --git a/res/values-en-rIN/strings.xml b/app/src/main/res/values-en-rIN/strings.xml similarity index 100% rename from res/values-en-rIN/strings.xml rename to app/src/main/res/values-en-rIN/strings.xml diff --git a/res/values-es-rMX/cm_strings.xml b/app/src/main/res/values-es-rMX/cm_strings.xml similarity index 100% rename from res/values-es-rMX/cm_strings.xml rename to app/src/main/res/values-es-rMX/cm_strings.xml diff --git a/res/values-es-rUS/arrays.xml b/app/src/main/res/values-es-rUS/arrays.xml similarity index 100% rename from res/values-es-rUS/arrays.xml rename to app/src/main/res/values-es-rUS/arrays.xml diff --git a/res/values-es-rUS/cm_strings.xml b/app/src/main/res/values-es-rUS/cm_strings.xml similarity index 100% rename from res/values-es-rUS/cm_strings.xml rename to app/src/main/res/values-es-rUS/cm_strings.xml diff --git a/res/values-es-rUS/strings.xml b/app/src/main/res/values-es-rUS/strings.xml similarity index 100% rename from res/values-es-rUS/strings.xml rename to app/src/main/res/values-es-rUS/strings.xml diff --git a/res/values-es/arrays.xml b/app/src/main/res/values-es/arrays.xml similarity index 100% rename from res/values-es/arrays.xml rename to app/src/main/res/values-es/arrays.xml diff --git a/res/values-es/cm_strings.xml b/app/src/main/res/values-es/cm_strings.xml similarity index 100% rename from res/values-es/cm_strings.xml rename to app/src/main/res/values-es/cm_strings.xml diff --git a/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml similarity index 100% rename from res/values-es/strings.xml rename to app/src/main/res/values-es/strings.xml diff --git a/res/values-et/arrays.xml b/app/src/main/res/values-et/arrays.xml similarity index 100% rename from res/values-et/arrays.xml rename to app/src/main/res/values-et/arrays.xml diff --git a/res/values-et/cm_strings.xml b/app/src/main/res/values-et/cm_strings.xml similarity index 100% rename from res/values-et/cm_strings.xml rename to app/src/main/res/values-et/cm_strings.xml diff --git a/res/values-et/strings.xml b/app/src/main/res/values-et/strings.xml similarity index 100% rename from res/values-et/strings.xml rename to app/src/main/res/values-et/strings.xml diff --git a/res/values-eu/arrays.xml b/app/src/main/res/values-eu/arrays.xml similarity index 100% rename from res/values-eu/arrays.xml rename to app/src/main/res/values-eu/arrays.xml diff --git a/res/values-eu/cm_strings.xml b/app/src/main/res/values-eu/cm_strings.xml similarity index 100% rename from res/values-eu/cm_strings.xml rename to app/src/main/res/values-eu/cm_strings.xml diff --git a/res/values-eu/strings.xml b/app/src/main/res/values-eu/strings.xml similarity index 100% rename from res/values-eu/strings.xml rename to app/src/main/res/values-eu/strings.xml diff --git a/res/values-fa/arrays.xml b/app/src/main/res/values-fa/arrays.xml similarity index 100% rename from res/values-fa/arrays.xml rename to app/src/main/res/values-fa/arrays.xml diff --git a/res/values-fa/cm_strings.xml b/app/src/main/res/values-fa/cm_strings.xml similarity index 100% rename from res/values-fa/cm_strings.xml rename to app/src/main/res/values-fa/cm_strings.xml diff --git a/res/values-fa/strings.xml b/app/src/main/res/values-fa/strings.xml similarity index 100% rename from res/values-fa/strings.xml rename to app/src/main/res/values-fa/strings.xml diff --git a/res/values-fi/arrays.xml b/app/src/main/res/values-fi/arrays.xml similarity index 100% rename from res/values-fi/arrays.xml rename to app/src/main/res/values-fi/arrays.xml diff --git a/res/values-fi/cm_strings.xml b/app/src/main/res/values-fi/cm_strings.xml similarity index 100% rename from res/values-fi/cm_strings.xml rename to app/src/main/res/values-fi/cm_strings.xml diff --git a/res/values-fi/strings.xml b/app/src/main/res/values-fi/strings.xml similarity index 100% rename from res/values-fi/strings.xml rename to app/src/main/res/values-fi/strings.xml diff --git a/res/values-fr-rCA/arrays.xml b/app/src/main/res/values-fr-rCA/arrays.xml similarity index 100% rename from res/values-fr-rCA/arrays.xml rename to app/src/main/res/values-fr-rCA/arrays.xml diff --git a/res/values-fr-rCA/strings.xml b/app/src/main/res/values-fr-rCA/strings.xml similarity index 100% rename from res/values-fr-rCA/strings.xml rename to app/src/main/res/values-fr-rCA/strings.xml diff --git a/res/values-fr/arrays.xml b/app/src/main/res/values-fr/arrays.xml similarity index 100% rename from res/values-fr/arrays.xml rename to app/src/main/res/values-fr/arrays.xml diff --git a/res/values-fr/cm_strings.xml b/app/src/main/res/values-fr/cm_strings.xml similarity index 100% rename from res/values-fr/cm_strings.xml rename to app/src/main/res/values-fr/cm_strings.xml diff --git a/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml similarity index 100% rename from res/values-fr/strings.xml rename to app/src/main/res/values-fr/strings.xml diff --git a/res/values-fur-rIT/cm_strings.xml b/app/src/main/res/values-fur-rIT/cm_strings.xml similarity index 100% rename from res/values-fur-rIT/cm_strings.xml rename to app/src/main/res/values-fur-rIT/cm_strings.xml diff --git a/res/values-fy-rNL/cm_strings.xml b/app/src/main/res/values-fy-rNL/cm_strings.xml similarity index 100% rename from res/values-fy-rNL/cm_strings.xml rename to app/src/main/res/values-fy-rNL/cm_strings.xml diff --git a/res/values-ga-rIE/cm_strings.xml b/app/src/main/res/values-ga-rIE/cm_strings.xml similarity index 100% rename from res/values-ga-rIE/cm_strings.xml rename to app/src/main/res/values-ga-rIE/cm_strings.xml diff --git a/res/values-gd/cm_strings.xml b/app/src/main/res/values-gd/cm_strings.xml similarity index 100% rename from res/values-gd/cm_strings.xml rename to app/src/main/res/values-gd/cm_strings.xml diff --git a/res/values-gl/arrays.xml b/app/src/main/res/values-gl/arrays.xml similarity index 100% rename from res/values-gl/arrays.xml rename to app/src/main/res/values-gl/arrays.xml diff --git a/res/values-gl/cm_strings.xml b/app/src/main/res/values-gl/cm_strings.xml similarity index 100% rename from res/values-gl/cm_strings.xml rename to app/src/main/res/values-gl/cm_strings.xml diff --git a/res/values-gl/strings.xml b/app/src/main/res/values-gl/strings.xml similarity index 100% rename from res/values-gl/strings.xml rename to app/src/main/res/values-gl/strings.xml diff --git a/res/values-gu/arrays.xml b/app/src/main/res/values-gu/arrays.xml similarity index 100% rename from res/values-gu/arrays.xml rename to app/src/main/res/values-gu/arrays.xml diff --git a/res/values-gu/cm_strings.xml b/app/src/main/res/values-gu/cm_strings.xml similarity index 100% rename from res/values-gu/cm_strings.xml rename to app/src/main/res/values-gu/cm_strings.xml diff --git a/res/values-gu/strings.xml b/app/src/main/res/values-gu/strings.xml similarity index 100% rename from res/values-gu/strings.xml rename to app/src/main/res/values-gu/strings.xml diff --git a/res/values-hi/arrays.xml b/app/src/main/res/values-hi/arrays.xml similarity index 100% rename from res/values-hi/arrays.xml rename to app/src/main/res/values-hi/arrays.xml diff --git a/res/values-hi/strings.xml b/app/src/main/res/values-hi/strings.xml similarity index 100% rename from res/values-hi/strings.xml rename to app/src/main/res/values-hi/strings.xml diff --git a/res/values-hr/arrays.xml b/app/src/main/res/values-hr/arrays.xml similarity index 100% rename from res/values-hr/arrays.xml rename to app/src/main/res/values-hr/arrays.xml diff --git a/res/values-hr/cm_strings.xml b/app/src/main/res/values-hr/cm_strings.xml similarity index 100% rename from res/values-hr/cm_strings.xml rename to app/src/main/res/values-hr/cm_strings.xml diff --git a/res/values-hr/strings.xml b/app/src/main/res/values-hr/strings.xml similarity index 100% rename from res/values-hr/strings.xml rename to app/src/main/res/values-hr/strings.xml diff --git a/res/values-hu/arrays.xml b/app/src/main/res/values-hu/arrays.xml similarity index 100% rename from res/values-hu/arrays.xml rename to app/src/main/res/values-hu/arrays.xml diff --git a/res/values-hu/cm_strings.xml b/app/src/main/res/values-hu/cm_strings.xml similarity index 100% rename from res/values-hu/cm_strings.xml rename to app/src/main/res/values-hu/cm_strings.xml diff --git a/res/values-hu/strings.xml b/app/src/main/res/values-hu/strings.xml similarity index 100% rename from res/values-hu/strings.xml rename to app/src/main/res/values-hu/strings.xml diff --git a/res/values-hy/arrays.xml b/app/src/main/res/values-hy/arrays.xml similarity index 100% rename from res/values-hy/arrays.xml rename to app/src/main/res/values-hy/arrays.xml diff --git a/res/values-hy/strings.xml b/app/src/main/res/values-hy/strings.xml similarity index 100% rename from res/values-hy/strings.xml rename to app/src/main/res/values-hy/strings.xml diff --git a/res/values-in/arrays.xml b/app/src/main/res/values-in/arrays.xml similarity index 100% rename from res/values-in/arrays.xml rename to app/src/main/res/values-in/arrays.xml diff --git a/res/values-in/cm_strings.xml b/app/src/main/res/values-in/cm_strings.xml similarity index 100% rename from res/values-in/cm_strings.xml rename to app/src/main/res/values-in/cm_strings.xml diff --git a/res/values-in/strings.xml b/app/src/main/res/values-in/strings.xml similarity index 100% rename from res/values-in/strings.xml rename to app/src/main/res/values-in/strings.xml diff --git a/res/values-is/arrays.xml b/app/src/main/res/values-is/arrays.xml similarity index 100% rename from res/values-is/arrays.xml rename to app/src/main/res/values-is/arrays.xml diff --git a/res/values-is/cm_strings.xml b/app/src/main/res/values-is/cm_strings.xml similarity index 100% rename from res/values-is/cm_strings.xml rename to app/src/main/res/values-is/cm_strings.xml diff --git a/res/values-is/strings.xml b/app/src/main/res/values-is/strings.xml similarity index 100% rename from res/values-is/strings.xml rename to app/src/main/res/values-is/strings.xml diff --git a/res/values-it/arrays.xml b/app/src/main/res/values-it/arrays.xml similarity index 100% rename from res/values-it/arrays.xml rename to app/src/main/res/values-it/arrays.xml diff --git a/res/values-it/cm_strings.xml b/app/src/main/res/values-it/cm_strings.xml similarity index 100% rename from res/values-it/cm_strings.xml rename to app/src/main/res/values-it/cm_strings.xml diff --git a/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml similarity index 100% rename from res/values-it/strings.xml rename to app/src/main/res/values-it/strings.xml diff --git a/res/values-iw/arrays.xml b/app/src/main/res/values-iw/arrays.xml similarity index 100% rename from res/values-iw/arrays.xml rename to app/src/main/res/values-iw/arrays.xml diff --git a/res/values-iw/cm_strings.xml b/app/src/main/res/values-iw/cm_strings.xml similarity index 100% rename from res/values-iw/cm_strings.xml rename to app/src/main/res/values-iw/cm_strings.xml diff --git a/res/values-iw/strings.xml b/app/src/main/res/values-iw/strings.xml similarity index 100% rename from res/values-iw/strings.xml rename to app/src/main/res/values-iw/strings.xml diff --git a/res/values-ja/arrays.xml b/app/src/main/res/values-ja/arrays.xml similarity index 100% rename from res/values-ja/arrays.xml rename to app/src/main/res/values-ja/arrays.xml diff --git a/res/values-ja/cm_strings.xml b/app/src/main/res/values-ja/cm_strings.xml similarity index 100% rename from res/values-ja/cm_strings.xml rename to app/src/main/res/values-ja/cm_strings.xml diff --git a/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml similarity index 100% rename from res/values-ja/strings.xml rename to app/src/main/res/values-ja/strings.xml diff --git a/res/values-ka/arrays.xml b/app/src/main/res/values-ka/arrays.xml similarity index 100% rename from res/values-ka/arrays.xml rename to app/src/main/res/values-ka/arrays.xml diff --git a/res/values-ka/cm_strings.xml b/app/src/main/res/values-ka/cm_strings.xml similarity index 100% rename from res/values-ka/cm_strings.xml rename to app/src/main/res/values-ka/cm_strings.xml diff --git a/res/values-ka/strings.xml b/app/src/main/res/values-ka/strings.xml similarity index 100% rename from res/values-ka/strings.xml rename to app/src/main/res/values-ka/strings.xml diff --git a/res/values-kab-rDZ/cm_strings.xml b/app/src/main/res/values-kab-rDZ/cm_strings.xml similarity index 100% rename from res/values-kab-rDZ/cm_strings.xml rename to app/src/main/res/values-kab-rDZ/cm_strings.xml diff --git a/res/values-kk/arrays.xml b/app/src/main/res/values-kk/arrays.xml similarity index 100% rename from res/values-kk/arrays.xml rename to app/src/main/res/values-kk/arrays.xml diff --git a/res/values-kk/strings.xml b/app/src/main/res/values-kk/strings.xml similarity index 100% rename from res/values-kk/strings.xml rename to app/src/main/res/values-kk/strings.xml diff --git a/res/values-km/arrays.xml b/app/src/main/res/values-km/arrays.xml similarity index 100% rename from res/values-km/arrays.xml rename to app/src/main/res/values-km/arrays.xml diff --git a/res/values-km/strings.xml b/app/src/main/res/values-km/strings.xml similarity index 100% rename from res/values-km/strings.xml rename to app/src/main/res/values-km/strings.xml diff --git a/res/values-kn/arrays.xml b/app/src/main/res/values-kn/arrays.xml similarity index 100% rename from res/values-kn/arrays.xml rename to app/src/main/res/values-kn/arrays.xml diff --git a/res/values-kn/cm_strings.xml b/app/src/main/res/values-kn/cm_strings.xml similarity index 100% rename from res/values-kn/cm_strings.xml rename to app/src/main/res/values-kn/cm_strings.xml diff --git a/res/values-kn/strings.xml b/app/src/main/res/values-kn/strings.xml similarity index 100% rename from res/values-kn/strings.xml rename to app/src/main/res/values-kn/strings.xml diff --git a/res/values-ko/arrays.xml b/app/src/main/res/values-ko/arrays.xml similarity index 100% rename from res/values-ko/arrays.xml rename to app/src/main/res/values-ko/arrays.xml diff --git a/res/values-ko/cm_strings.xml b/app/src/main/res/values-ko/cm_strings.xml similarity index 100% rename from res/values-ko/cm_strings.xml rename to app/src/main/res/values-ko/cm_strings.xml diff --git a/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml similarity index 100% rename from res/values-ko/strings.xml rename to app/src/main/res/values-ko/strings.xml diff --git a/res/values-ky/arrays.xml b/app/src/main/res/values-ky/arrays.xml similarity index 100% rename from res/values-ky/arrays.xml rename to app/src/main/res/values-ky/arrays.xml diff --git a/res/values-ky/strings.xml b/app/src/main/res/values-ky/strings.xml similarity index 100% rename from res/values-ky/strings.xml rename to app/src/main/res/values-ky/strings.xml diff --git a/res/values-lb/cm_strings.xml b/app/src/main/res/values-lb/cm_strings.xml similarity index 100% rename from res/values-lb/cm_strings.xml rename to app/src/main/res/values-lb/cm_strings.xml diff --git a/res/values-lo/arrays.xml b/app/src/main/res/values-lo/arrays.xml similarity index 100% rename from res/values-lo/arrays.xml rename to app/src/main/res/values-lo/arrays.xml diff --git a/res/values-lo/strings.xml b/app/src/main/res/values-lo/strings.xml similarity index 100% rename from res/values-lo/strings.xml rename to app/src/main/res/values-lo/strings.xml diff --git a/res/values-lt/arrays.xml b/app/src/main/res/values-lt/arrays.xml similarity index 100% rename from res/values-lt/arrays.xml rename to app/src/main/res/values-lt/arrays.xml diff --git a/res/values-lt/strings.xml b/app/src/main/res/values-lt/strings.xml similarity index 100% rename from res/values-lt/strings.xml rename to app/src/main/res/values-lt/strings.xml diff --git a/res/values-lv/arrays.xml b/app/src/main/res/values-lv/arrays.xml similarity index 100% rename from res/values-lv/arrays.xml rename to app/src/main/res/values-lv/arrays.xml diff --git a/res/values-lv/strings.xml b/app/src/main/res/values-lv/strings.xml similarity index 100% rename from res/values-lv/strings.xml rename to app/src/main/res/values-lv/strings.xml diff --git a/res/values-mk/arrays.xml b/app/src/main/res/values-mk/arrays.xml similarity index 100% rename from res/values-mk/arrays.xml rename to app/src/main/res/values-mk/arrays.xml diff --git a/res/values-mk/strings.xml b/app/src/main/res/values-mk/strings.xml similarity index 100% rename from res/values-mk/strings.xml rename to app/src/main/res/values-mk/strings.xml diff --git a/res/values-ml/arrays.xml b/app/src/main/res/values-ml/arrays.xml similarity index 100% rename from res/values-ml/arrays.xml rename to app/src/main/res/values-ml/arrays.xml diff --git a/res/values-ml/cm_strings.xml b/app/src/main/res/values-ml/cm_strings.xml similarity index 100% rename from res/values-ml/cm_strings.xml rename to app/src/main/res/values-ml/cm_strings.xml diff --git a/res/values-ml/strings.xml b/app/src/main/res/values-ml/strings.xml similarity index 100% rename from res/values-ml/strings.xml rename to app/src/main/res/values-ml/strings.xml diff --git a/res/values-mn/arrays.xml b/app/src/main/res/values-mn/arrays.xml similarity index 100% rename from res/values-mn/arrays.xml rename to app/src/main/res/values-mn/arrays.xml diff --git a/res/values-mn/strings.xml b/app/src/main/res/values-mn/strings.xml similarity index 100% rename from res/values-mn/strings.xml rename to app/src/main/res/values-mn/strings.xml diff --git a/res/values-mr/arrays.xml b/app/src/main/res/values-mr/arrays.xml similarity index 100% rename from res/values-mr/arrays.xml rename to app/src/main/res/values-mr/arrays.xml diff --git a/res/values-mr/cm_strings.xml b/app/src/main/res/values-mr/cm_strings.xml similarity index 100% rename from res/values-mr/cm_strings.xml rename to app/src/main/res/values-mr/cm_strings.xml diff --git a/res/values-mr/strings.xml b/app/src/main/res/values-mr/strings.xml similarity index 100% rename from res/values-mr/strings.xml rename to app/src/main/res/values-mr/strings.xml diff --git a/res/values-ms/arrays.xml b/app/src/main/res/values-ms/arrays.xml similarity index 100% rename from res/values-ms/arrays.xml rename to app/src/main/res/values-ms/arrays.xml diff --git a/res/values-ms/strings.xml b/app/src/main/res/values-ms/strings.xml similarity index 100% rename from res/values-ms/strings.xml rename to app/src/main/res/values-ms/strings.xml diff --git a/res/values-my/arrays.xml b/app/src/main/res/values-my/arrays.xml similarity index 100% rename from res/values-my/arrays.xml rename to app/src/main/res/values-my/arrays.xml diff --git a/res/values-my/strings.xml b/app/src/main/res/values-my/strings.xml similarity index 100% rename from res/values-my/strings.xml rename to app/src/main/res/values-my/strings.xml diff --git a/res/values-nb/arrays.xml b/app/src/main/res/values-nb/arrays.xml similarity index 100% rename from res/values-nb/arrays.xml rename to app/src/main/res/values-nb/arrays.xml diff --git a/res/values-nb/cm_strings.xml b/app/src/main/res/values-nb/cm_strings.xml similarity index 100% rename from res/values-nb/cm_strings.xml rename to app/src/main/res/values-nb/cm_strings.xml diff --git a/res/values-nb/strings.xml b/app/src/main/res/values-nb/strings.xml similarity index 100% rename from res/values-nb/strings.xml rename to app/src/main/res/values-nb/strings.xml diff --git a/res/values-ne/arrays.xml b/app/src/main/res/values-ne/arrays.xml similarity index 100% rename from res/values-ne/arrays.xml rename to app/src/main/res/values-ne/arrays.xml diff --git a/res/values-ne/strings.xml b/app/src/main/res/values-ne/strings.xml similarity index 100% rename from res/values-ne/strings.xml rename to app/src/main/res/values-ne/strings.xml diff --git a/app/src/main/res/values-night/colors.xml b/app/src/main/res/values-night/colors.xml new file mode 100644 index 0000000..56ce971 --- /dev/null +++ b/app/src/main/res/values-night/colors.xml @@ -0,0 +1,23 @@ + + + @color/looply_surface_alt + + @color/looply_text_primary + @color/looply_surface + @color/looply_primary_dark + + @color/looply_text_primary + @color/looply_text_secondary + @color/looply_text_secondary + @color/looply_text_primary + + @color/looply_bubble_incoming_text + @color/looply_bubble_outgoing_text + @color/looply_bubble_outgoing + @color/looply_bubble_incoming + #B3FFFFFF + #99A0A0C0 + + @color/looply_text_secondary + @color/looply_bg + diff --git a/app/src/main/res/values-night/lineage_bools.xml b/app/src/main/res/values-night/lineage_bools.xml new file mode 100644 index 0000000..ec5aee2 --- /dev/null +++ b/app/src/main/res/values-night/lineage_bools.xml @@ -0,0 +1,5 @@ + + + false + false + diff --git a/res/values-night/lineage_colors.xml b/app/src/main/res/values-night/lineage_colors.xml similarity index 60% rename from res/values-night/lineage_colors.xml rename to app/src/main/res/values-night/lineage_colors.xml index 1958fb2..9f7824a 100644 --- a/res/values-night/lineage_colors.xml +++ b/app/src/main/res/values-night/lineage_colors.xml @@ -16,14 +16,16 @@ limitations under the License. --> - @android:color/system_accent1_100 + @color/looply_primary - @android:color/system_neutral1_900 + @color/looply_bg - @android:color/system_neutral1_600 + @color/looply_surface - @android:color/black + @color/looply_surface_alt - @android:color/system_neutral1_800 - @android:color/system_accent1_800 + @color/looply_text_on_primary + + @color/looply_surface_alt + @color/looply_surface_alt diff --git a/app/src/main/res/values-night/looply_colors.xml b/app/src/main/res/values-night/looply_colors.xml new file mode 100644 index 0000000..be9d41f --- /dev/null +++ b/app/src/main/res/values-night/looply_colors.xml @@ -0,0 +1,37 @@ + + + + #706CFF + #5D5FEF + #2A2A4A + #1E1E30 + + #0A0A1B + #181829 + #262647 + #2E2E48 + + #FFFFFF + #A0A0C0 + #6B6B8A + #FFFFFF + + #5D5FEF + #FFFFFF + #262647 + #FFFFFF + + #22C55E + #706CFF + #EF4444 + #F97316 + + #262647 + #3A3A5C + #262647 + #E5E5F0 + #6B6B8A + #CC000000 + diff --git a/app/src/main/res/values-night/looply_styles.xml b/app/src/main/res/values-night/looply_styles.xml new file mode 100644 index 0000000..c1a3d16 --- /dev/null +++ b/app/src/main/res/values-night/looply_styles.xml @@ -0,0 +1,12 @@ + + + + diff --git a/app/src/main/res/values-night/styles.xml b/app/src/main/res/values-night/styles.xml new file mode 100644 index 0000000..a983777 --- /dev/null +++ b/app/src/main/res/values-night/styles.xml @@ -0,0 +1,12 @@ + + + + + diff --git a/res/values-nl/arrays.xml b/app/src/main/res/values-nl/arrays.xml similarity index 100% rename from res/values-nl/arrays.xml rename to app/src/main/res/values-nl/arrays.xml diff --git a/res/values-nl/cm_strings.xml b/app/src/main/res/values-nl/cm_strings.xml similarity index 100% rename from res/values-nl/cm_strings.xml rename to app/src/main/res/values-nl/cm_strings.xml diff --git a/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml similarity index 100% rename from res/values-nl/strings.xml rename to app/src/main/res/values-nl/strings.xml diff --git a/res/values-nn-rNO/cm_strings.xml b/app/src/main/res/values-nn-rNO/cm_strings.xml similarity index 100% rename from res/values-nn-rNO/cm_strings.xml rename to app/src/main/res/values-nn-rNO/cm_strings.xml diff --git a/res/values-or/cm_strings.xml b/app/src/main/res/values-or/cm_strings.xml similarity index 100% rename from res/values-or/cm_strings.xml rename to app/src/main/res/values-or/cm_strings.xml diff --git a/res/values-pa/arrays.xml b/app/src/main/res/values-pa/arrays.xml similarity index 100% rename from res/values-pa/arrays.xml rename to app/src/main/res/values-pa/arrays.xml diff --git a/res/values-pa/strings.xml b/app/src/main/res/values-pa/strings.xml similarity index 100% rename from res/values-pa/strings.xml rename to app/src/main/res/values-pa/strings.xml diff --git a/res/values-pl/arrays.xml b/app/src/main/res/values-pl/arrays.xml similarity index 100% rename from res/values-pl/arrays.xml rename to app/src/main/res/values-pl/arrays.xml diff --git a/res/values-pl/cm_strings.xml b/app/src/main/res/values-pl/cm_strings.xml similarity index 100% rename from res/values-pl/cm_strings.xml rename to app/src/main/res/values-pl/cm_strings.xml diff --git a/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml similarity index 100% rename from res/values-pl/strings.xml rename to app/src/main/res/values-pl/strings.xml diff --git a/res/values-pt-rBR/cm_strings.xml b/app/src/main/res/values-pt-rBR/cm_strings.xml similarity index 100% rename from res/values-pt-rBR/cm_strings.xml rename to app/src/main/res/values-pt-rBR/cm_strings.xml diff --git a/res/values-pt-rPT/arrays.xml b/app/src/main/res/values-pt-rPT/arrays.xml similarity index 100% rename from res/values-pt-rPT/arrays.xml rename to app/src/main/res/values-pt-rPT/arrays.xml diff --git a/res/values-pt-rPT/cm_strings.xml b/app/src/main/res/values-pt-rPT/cm_strings.xml similarity index 100% rename from res/values-pt-rPT/cm_strings.xml rename to app/src/main/res/values-pt-rPT/cm_strings.xml diff --git a/res/values-pt-rPT/strings.xml b/app/src/main/res/values-pt-rPT/strings.xml similarity index 100% rename from res/values-pt-rPT/strings.xml rename to app/src/main/res/values-pt-rPT/strings.xml diff --git a/res/values-pt/arrays.xml b/app/src/main/res/values-pt/arrays.xml similarity index 100% rename from res/values-pt/arrays.xml rename to app/src/main/res/values-pt/arrays.xml diff --git a/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml similarity index 100% rename from res/values-pt/strings.xml rename to app/src/main/res/values-pt/strings.xml diff --git a/res/values-ro/arrays.xml b/app/src/main/res/values-ro/arrays.xml similarity index 100% rename from res/values-ro/arrays.xml rename to app/src/main/res/values-ro/arrays.xml diff --git a/res/values-ro/cm_strings.xml b/app/src/main/res/values-ro/cm_strings.xml similarity index 100% rename from res/values-ro/cm_strings.xml rename to app/src/main/res/values-ro/cm_strings.xml diff --git a/res/values-ro/strings.xml b/app/src/main/res/values-ro/strings.xml similarity index 100% rename from res/values-ro/strings.xml rename to app/src/main/res/values-ro/strings.xml diff --git a/res/values-ru/arrays.xml b/app/src/main/res/values-ru/arrays.xml similarity index 100% rename from res/values-ru/arrays.xml rename to app/src/main/res/values-ru/arrays.xml diff --git a/res/values-ru/cm_strings.xml b/app/src/main/res/values-ru/cm_strings.xml similarity index 100% rename from res/values-ru/cm_strings.xml rename to app/src/main/res/values-ru/cm_strings.xml diff --git a/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml similarity index 100% rename from res/values-ru/strings.xml rename to app/src/main/res/values-ru/strings.xml diff --git a/res/values-sc-rIT/cm_strings.xml b/app/src/main/res/values-sc-rIT/cm_strings.xml similarity index 100% rename from res/values-sc-rIT/cm_strings.xml rename to app/src/main/res/values-sc-rIT/cm_strings.xml diff --git a/res/values-si/arrays.xml b/app/src/main/res/values-si/arrays.xml similarity index 100% rename from res/values-si/arrays.xml rename to app/src/main/res/values-si/arrays.xml diff --git a/res/values-si/strings.xml b/app/src/main/res/values-si/strings.xml similarity index 100% rename from res/values-si/strings.xml rename to app/src/main/res/values-si/strings.xml diff --git a/res/values-sk/arrays.xml b/app/src/main/res/values-sk/arrays.xml similarity index 100% rename from res/values-sk/arrays.xml rename to app/src/main/res/values-sk/arrays.xml diff --git a/res/values-sk/cm_strings.xml b/app/src/main/res/values-sk/cm_strings.xml similarity index 100% rename from res/values-sk/cm_strings.xml rename to app/src/main/res/values-sk/cm_strings.xml diff --git a/res/values-sk/strings.xml b/app/src/main/res/values-sk/strings.xml similarity index 100% rename from res/values-sk/strings.xml rename to app/src/main/res/values-sk/strings.xml diff --git a/res/values-sl/arrays.xml b/app/src/main/res/values-sl/arrays.xml similarity index 100% rename from res/values-sl/arrays.xml rename to app/src/main/res/values-sl/arrays.xml diff --git a/res/values-sl/cm_strings.xml b/app/src/main/res/values-sl/cm_strings.xml similarity index 100% rename from res/values-sl/cm_strings.xml rename to app/src/main/res/values-sl/cm_strings.xml diff --git a/res/values-sl/strings.xml b/app/src/main/res/values-sl/strings.xml similarity index 100% rename from res/values-sl/strings.xml rename to app/src/main/res/values-sl/strings.xml diff --git a/res/values-sq/arrays.xml b/app/src/main/res/values-sq/arrays.xml similarity index 100% rename from res/values-sq/arrays.xml rename to app/src/main/res/values-sq/arrays.xml diff --git a/res/values-sq/cm_strings.xml b/app/src/main/res/values-sq/cm_strings.xml similarity index 100% rename from res/values-sq/cm_strings.xml rename to app/src/main/res/values-sq/cm_strings.xml diff --git a/res/values-sq/strings.xml b/app/src/main/res/values-sq/strings.xml similarity index 100% rename from res/values-sq/strings.xml rename to app/src/main/res/values-sq/strings.xml diff --git a/res/values-sr/arrays.xml b/app/src/main/res/values-sr/arrays.xml similarity index 100% rename from res/values-sr/arrays.xml rename to app/src/main/res/values-sr/arrays.xml diff --git a/res/values-sr/cm_strings.xml b/app/src/main/res/values-sr/cm_strings.xml similarity index 100% rename from res/values-sr/cm_strings.xml rename to app/src/main/res/values-sr/cm_strings.xml diff --git a/res/values-sr/strings.xml b/app/src/main/res/values-sr/strings.xml similarity index 100% rename from res/values-sr/strings.xml rename to app/src/main/res/values-sr/strings.xml diff --git a/res/values-sv/arrays.xml b/app/src/main/res/values-sv/arrays.xml similarity index 100% rename from res/values-sv/arrays.xml rename to app/src/main/res/values-sv/arrays.xml diff --git a/res/values-sv/cm_strings.xml b/app/src/main/res/values-sv/cm_strings.xml similarity index 100% rename from res/values-sv/cm_strings.xml rename to app/src/main/res/values-sv/cm_strings.xml diff --git a/res/values-sv/strings.xml b/app/src/main/res/values-sv/strings.xml similarity index 100% rename from res/values-sv/strings.xml rename to app/src/main/res/values-sv/strings.xml diff --git a/res/values-sw/arrays.xml b/app/src/main/res/values-sw/arrays.xml similarity index 100% rename from res/values-sw/arrays.xml rename to app/src/main/res/values-sw/arrays.xml diff --git a/res/values-sw/strings.xml b/app/src/main/res/values-sw/strings.xml similarity index 100% rename from res/values-sw/strings.xml rename to app/src/main/res/values-sw/strings.xml diff --git a/res/values-ta/arrays.xml b/app/src/main/res/values-ta/arrays.xml similarity index 100% rename from res/values-ta/arrays.xml rename to app/src/main/res/values-ta/arrays.xml diff --git a/res/values-ta/cm_strings.xml b/app/src/main/res/values-ta/cm_strings.xml similarity index 100% rename from res/values-ta/cm_strings.xml rename to app/src/main/res/values-ta/cm_strings.xml diff --git a/res/values-ta/strings.xml b/app/src/main/res/values-ta/strings.xml similarity index 100% rename from res/values-ta/strings.xml rename to app/src/main/res/values-ta/strings.xml diff --git a/res/values-te/arrays.xml b/app/src/main/res/values-te/arrays.xml similarity index 100% rename from res/values-te/arrays.xml rename to app/src/main/res/values-te/arrays.xml diff --git a/res/values-te/cm_strings.xml b/app/src/main/res/values-te/cm_strings.xml similarity index 100% rename from res/values-te/cm_strings.xml rename to app/src/main/res/values-te/cm_strings.xml diff --git a/res/values-te/strings.xml b/app/src/main/res/values-te/strings.xml similarity index 100% rename from res/values-te/strings.xml rename to app/src/main/res/values-te/strings.xml diff --git a/res/values-th/arrays.xml b/app/src/main/res/values-th/arrays.xml similarity index 100% rename from res/values-th/arrays.xml rename to app/src/main/res/values-th/arrays.xml diff --git a/res/values-th/cm_strings.xml b/app/src/main/res/values-th/cm_strings.xml similarity index 100% rename from res/values-th/cm_strings.xml rename to app/src/main/res/values-th/cm_strings.xml diff --git a/res/values-th/strings.xml b/app/src/main/res/values-th/strings.xml similarity index 100% rename from res/values-th/strings.xml rename to app/src/main/res/values-th/strings.xml diff --git a/res/values-tl/arrays.xml b/app/src/main/res/values-tl/arrays.xml similarity index 100% rename from res/values-tl/arrays.xml rename to app/src/main/res/values-tl/arrays.xml diff --git a/res/values-tl/strings.xml b/app/src/main/res/values-tl/strings.xml similarity index 100% rename from res/values-tl/strings.xml rename to app/src/main/res/values-tl/strings.xml diff --git a/res/values-tr/arrays.xml b/app/src/main/res/values-tr/arrays.xml similarity index 100% rename from res/values-tr/arrays.xml rename to app/src/main/res/values-tr/arrays.xml diff --git a/res/values-tr/cm_strings.xml b/app/src/main/res/values-tr/cm_strings.xml similarity index 100% rename from res/values-tr/cm_strings.xml rename to app/src/main/res/values-tr/cm_strings.xml diff --git a/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml similarity index 100% rename from res/values-tr/strings.xml rename to app/src/main/res/values-tr/strings.xml diff --git a/res/values-ug/cm_strings.xml b/app/src/main/res/values-ug/cm_strings.xml similarity index 100% rename from res/values-ug/cm_strings.xml rename to app/src/main/res/values-ug/cm_strings.xml diff --git a/res/values-uk/arrays.xml b/app/src/main/res/values-uk/arrays.xml similarity index 100% rename from res/values-uk/arrays.xml rename to app/src/main/res/values-uk/arrays.xml diff --git a/res/values-uk/cm_strings.xml b/app/src/main/res/values-uk/cm_strings.xml similarity index 100% rename from res/values-uk/cm_strings.xml rename to app/src/main/res/values-uk/cm_strings.xml diff --git a/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml similarity index 100% rename from res/values-uk/strings.xml rename to app/src/main/res/values-uk/strings.xml diff --git a/res/values-ur/arrays.xml b/app/src/main/res/values-ur/arrays.xml similarity index 100% rename from res/values-ur/arrays.xml rename to app/src/main/res/values-ur/arrays.xml diff --git a/res/values-ur/strings.xml b/app/src/main/res/values-ur/strings.xml similarity index 100% rename from res/values-ur/strings.xml rename to app/src/main/res/values-ur/strings.xml diff --git a/res/values-uz/arrays.xml b/app/src/main/res/values-uz/arrays.xml similarity index 100% rename from res/values-uz/arrays.xml rename to app/src/main/res/values-uz/arrays.xml diff --git a/res/values-uz/strings.xml b/app/src/main/res/values-uz/strings.xml similarity index 100% rename from res/values-uz/strings.xml rename to app/src/main/res/values-uz/strings.xml diff --git a/res/values-vi/arrays.xml b/app/src/main/res/values-vi/arrays.xml similarity index 100% rename from res/values-vi/arrays.xml rename to app/src/main/res/values-vi/arrays.xml diff --git a/res/values-vi/cm_strings.xml b/app/src/main/res/values-vi/cm_strings.xml similarity index 100% rename from res/values-vi/cm_strings.xml rename to app/src/main/res/values-vi/cm_strings.xml diff --git a/res/values-vi/strings.xml b/app/src/main/res/values-vi/strings.xml similarity index 100% rename from res/values-vi/strings.xml rename to app/src/main/res/values-vi/strings.xml diff --git a/res/values-zh-rCN/arrays.xml b/app/src/main/res/values-zh-rCN/arrays.xml similarity index 100% rename from res/values-zh-rCN/arrays.xml rename to app/src/main/res/values-zh-rCN/arrays.xml diff --git a/res/values-zh-rCN/cm_strings.xml b/app/src/main/res/values-zh-rCN/cm_strings.xml similarity index 100% rename from res/values-zh-rCN/cm_strings.xml rename to app/src/main/res/values-zh-rCN/cm_strings.xml diff --git a/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml similarity index 100% rename from res/values-zh-rCN/strings.xml rename to app/src/main/res/values-zh-rCN/strings.xml diff --git a/res/values-zh-rHK/arrays.xml b/app/src/main/res/values-zh-rHK/arrays.xml similarity index 100% rename from res/values-zh-rHK/arrays.xml rename to app/src/main/res/values-zh-rHK/arrays.xml diff --git a/res/values-zh-rHK/strings.xml b/app/src/main/res/values-zh-rHK/strings.xml similarity index 100% rename from res/values-zh-rHK/strings.xml rename to app/src/main/res/values-zh-rHK/strings.xml diff --git a/res/values-zh-rTW/arrays.xml b/app/src/main/res/values-zh-rTW/arrays.xml similarity index 100% rename from res/values-zh-rTW/arrays.xml rename to app/src/main/res/values-zh-rTW/arrays.xml diff --git a/res/values-zh-rTW/cm_strings.xml b/app/src/main/res/values-zh-rTW/cm_strings.xml similarity index 100% rename from res/values-zh-rTW/cm_strings.xml rename to app/src/main/res/values-zh-rTW/cm_strings.xml diff --git a/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml similarity index 100% rename from res/values-zh-rTW/strings.xml rename to app/src/main/res/values-zh-rTW/strings.xml diff --git a/res/values-zu/arrays.xml b/app/src/main/res/values-zu/arrays.xml similarity index 100% rename from res/values-zu/arrays.xml rename to app/src/main/res/values-zu/arrays.xml diff --git a/res/values-zu/strings.xml b/app/src/main/res/values-zu/strings.xml similarity index 100% rename from res/values-zu/strings.xml rename to app/src/main/res/values-zu/strings.xml diff --git a/res/values/arrays.xml b/app/src/main/res/values/arrays.xml similarity index 100% rename from res/values/arrays.xml rename to app/src/main/res/values/arrays.xml diff --git a/res/values/attrs.xml b/app/src/main/res/values/attrs.xml similarity index 100% rename from res/values/attrs.xml rename to app/src/main/res/values/attrs.xml diff --git a/res/values/cm_strings.xml b/app/src/main/res/values/cm_strings.xml similarity index 100% rename from res/values/cm_strings.xml rename to app/src/main/res/values/cm_strings.xml diff --git a/res/values/colors.xml b/app/src/main/res/values/colors.xml similarity index 50% rename from res/values/colors.xml rename to app/src/main/res/values/colors.xml index 1b48f34..67cc7af 100644 --- a/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -16,94 +16,95 @@ limitations under the License. --> - @android:color/system_accent1_600 + @color/looply_primary @color/primary_color - - @android:color/system_neutral1_0 - @android:color/system_accent1_600 - @android:color/system_accent1_700 - @android:color/system_accent1_600 - @android:color/system_accent1_700 - @android:color/system_accent1_600 + + @color/looply_text_primary + @color/looply_surface + @color/looply_primary_dark + @color/looply_primary + @color/looply_primary_dark + @color/looply_primary - #636363 - #323232 - #F05A24 - #DE000000 - #8A000000 + @color/looply_text_secondary + @color/looply_text_primary + @color/looply_warning + @color/looply_text_primary + @color/looply_text_secondary #44000000 - #000000 - #99323232 - #99ffffff + @color/looply_text_primary + #B3FFFFFF + #991A0D3F #99ff0000 - #000000 + @color/looply_text_primary - #ff323232 - #000000 + @color/looply_text_primary + @color/looply_text_primary #99ffffff - #6a6a6a - #007fce + @color/looply_text_secondary + @color/looply_primary #99ff0000 #ffffffff #99ffffff #ffffffff - #6733b5e5 + #335A31F4 - #ffffffff - #ffffffff - #6a6a6a - #ff323232 + @color/looply_surface + @color/looply_bubble_incoming_text + @color/looply_text_secondary + @color/looply_bubble_outgoing_text @color/window_background - #9d9d9d + @color/looply_primary_soft @color/lineage_accent - #999999 - #ffffffff + @color/looply_primary_dark + @color/looply_bubble_outgoing + @color/looply_bubble_incoming #e2e2e2 - #ffffffff - @android:color/system_accent3_300 + @color/looply_primary + @color/looply_primary_soft #7f040000 #ff0000 #40000000 - #4d4d4d - #999999 + @color/looply_text_primary + @color/looply_text_secondary - @android:color/white - #a0ffffff - #44000000 - #ddffffff - @android:color/white - @color/lineage_accent - #ffffff - #4285f4 - #ededed - #33000000 - @android:color/white + @color/looply_text_primary + @color/looply_text_hint + @color/looply_divider + @color/looply_primary_soft + @color/looply_primary + @color/looply_primary + @color/looply_bg + @color/looply_primary + @color/looply_primary_muted + @color/looply_primary + @color/looply_text_on_primary #80ffffff #44000000 - @android:color/system_accent1_300 - @android:color/system_accent2_300 - @android:color/system_accent3_300 - @android:color/system_accent1_400 - @android:color/system_accent2_400 - @android:color/system_accent3_400 - @android:color/system_accent1_500 - @android:color/system_accent2_500 - @android:color/system_accent3_500 - @android:color/system_accent1_600 - @android:color/system_accent2_600 - @android:color/system_accent3_600 + #5A31F4 + #706CFF + #4B00D1 + #7C4DFF + #651FFF + #536DFE + #3D5AFE + #8B5CF6 + #6D28D9 + #5B21B6 + #4C1D95 + #4338CA #ffffff @@ -115,7 +116,7 @@ #323232 @color/lineage_accent - #40000000 + @color/looply_text_hint #DE000000 #8A000000 @@ -129,22 +130,22 @@ #6d6d6d #cccccc - @color/lineage_accent + @color/looply_primary - #555555 - #681faf - #6d6d6d + @color/looply_text_secondary + @color/looply_primary + @color/looply_text_secondary @color/lineage_accent #40000000 - @color/primary_color + @color/looply_bg #4d4d4d #999999 #cceeeeee #ffeeeeee - @android:color/system_accent1_100 - #b0dddddd + @color/looply_primary_soft + @color/looply_primary #4d4d4d #6d6d6d diff --git a/res/values/config.xml b/app/src/main/res/values/config.xml similarity index 100% rename from res/values/config.xml rename to app/src/main/res/values/config.xml diff --git a/res/values/constants.xml b/app/src/main/res/values/constants.xml similarity index 100% rename from res/values/constants.xml rename to app/src/main/res/values/constants.xml diff --git a/res/values/dimens.xml b/app/src/main/res/values/dimens.xml similarity index 98% rename from res/values/dimens.xml rename to app/src/main/res/values/dimens.xml index 72c1c86..a9e5c81 100644 --- a/res/values/dimens.xml +++ b/app/src/main/res/values/dimens.xml @@ -24,8 +24,8 @@ 12sp 12sp 16sp - 42dp - 56dp + 34dp + 45dp 12dp 16dp 8dp diff --git a/app/src/main/res/values/home_colors.xml b/app/src/main/res/values/home_colors.xml new file mode 100644 index 0000000..a138635 --- /dev/null +++ b/app/src/main/res/values/home_colors.xml @@ -0,0 +1,35 @@ + + + + #FFFFFF + #F2F2F7 + #E5E5EA + #E8FFFFFF + #F2FFFFFF + #14000000 + + #12000000 + #0C000000 + #05000000 + #08000000 + #0E000000 + #F2F2F7 + #F5FFFFFF + #CCFFFFFF + #00FFFFFF + #E5E5EA + #000000 + #8E8E93 + #AEAEB2 + + #1C1C1E + @color/looply_primary_soft + #48484A + #3A3A3C + #FFFFFF + @color/looply_primary + @color/looply_primary_soft + #E8E8ED + #6C6C70 + #FFD60A + diff --git a/app/src/main/res/values/home_ids.xml b/app/src/main/res/values/home_ids.xml new file mode 100644 index 0000000..e5fd354 --- /dev/null +++ b/app/src/main/res/values/home_ids.xml @@ -0,0 +1,4 @@ + + + + diff --git a/app/src/main/res/values/home_styles.xml b/app/src/main/res/values/home_styles.xml new file mode 100644 index 0000000..87581fc --- /dev/null +++ b/app/src/main/res/values/home_styles.xml @@ -0,0 +1,39 @@ + + + + + + + diff --git a/res/values/lineage_bools.xml b/app/src/main/res/values/lineage_bools.xml similarity index 100% rename from res/values/lineage_bools.xml rename to app/src/main/res/values/lineage_bools.xml diff --git a/res/values/lineage_colors.xml b/app/src/main/res/values/lineage_colors.xml similarity index 62% rename from res/values/lineage_colors.xml rename to app/src/main/res/values/lineage_colors.xml index 77ee55a..14b69dd 100644 --- a/res/values/lineage_colors.xml +++ b/app/src/main/res/values/lineage_colors.xml @@ -16,15 +16,16 @@ limitations under the License. --> - @android:color/system_accent1_600 + + @color/looply_primary - @android:color/system_neutral1_50 + @color/looply_bg - @color/window_background + @color/looply_surface - @android:color/white + @color/looply_surface - @android:color/white + @color/looply_text_on_primary - @android:color/system_neutral1_0 + @color/looply_surface diff --git a/res/values/lineage_constants.xml b/app/src/main/res/values/lineage_constants.xml similarity index 100% rename from res/values/lineage_constants.xml rename to app/src/main/res/values/lineage_constants.xml diff --git a/app/src/main/res/values/looply_colors.xml b/app/src/main/res/values/looply_colors.xml new file mode 100644 index 0000000..4ef44bb --- /dev/null +++ b/app/src/main/res/values/looply_colors.xml @@ -0,0 +1,44 @@ + + + + + #5A31F4 + #4B00D1 + #E8E6FF + #F3F1FF + + + #F3F4FB + #FFFFFF + #F9F9F9 + #E8E8F0 + + + #1A0D3F + #757575 + #9E9EAE + #FFFFFF + + + #5A31F4 + #FFFFFF + #F0EFF8 + #1A0D3F + + + #22C55E + #5A31F4 + #EF4444 + #F97316 + + + #FFFFFF + #E5E5EF + #EEEAF8 + #1A0D3F + #9CA3AF + #99000000 + diff --git a/app/src/main/res/values/looply_dimens.xml b/app/src/main/res/values/looply_dimens.xml new file mode 100644 index 0000000..0f001e7 --- /dev/null +++ b/app/src/main/res/values/looply_dimens.xml @@ -0,0 +1,77 @@ + + + + 8dp + 12dp + 16dp + 20dp + 24dp + 999dp + + + 4dp + 8dp + 12dp + 16dp + 20dp + 24dp + 20dp + + + 52dp + 52dp + 48dp + 36dp + + 38dp + 74dp + 104dp + 45dp + + 96dp + 132dp + + 18dp + + 46dp + 8dp + 12dp + 120dp + 16dp + 14dp + 10dp + 6dp + + 12dp + 22dp + -4dp + 20dp + 8dp + + 12dp + 22dp + 12dp + 56dp + 10dp + 72dp + 64dp + 24dp + 55dp + 5dp + + 6dp + 3dp + 3dp + 70dp + 6dp + 280dp + 14dp + 10dp + + + 22sp + 18sp + 15sp + 13sp + 12sp + diff --git a/app/src/main/res/values/looply_strings.xml b/app/src/main/res/values/looply_strings.xml new file mode 100644 index 0000000..6e62a47 --- /dev/null +++ b/app/src/main/res/values/looply_strings.xml @@ -0,0 +1,74 @@ + + + Looply Components + Search by name or number + All + Unread + Groups + Type a message + Chats + Calls + Contacts + Settings + + + Messages + Edit + Search + Personal + Work + All + Unread + Groups + Archived + Search + Filter + New message + Voice input + Automate is coming soon + Start chat + + All Messages + Unread + Groups + Archived + Messages + Contacts + Calls + Settings + Automate + Contacts + Search contacts + Invite friends + Recent call history + Sorted by last seen + Sort contacts + Add contact + Read All + Done + Delete selected messages + Add + Calls coming soon + More options + + + Messages + Spam + Recently Deleted + Filter By + Unread + Work + Personal + Settings + Select Messages + Edit Pinned + Name and Photo Settings + Coming soon + + Pinned Conversations + You can pin up to 9 conversations. To pin this conversation, unpin another one first. + OK + Pin conversation + Unpin conversation + Remove pin + diff --git a/app/src/main/res/values/looply_styles.xml b/app/src/main/res/values/looply_styles.xml new file mode 100644 index 0000000..fd9864c --- /dev/null +++ b/app/src/main/res/values/looply_styles.xml @@ -0,0 +1,158 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/values/strings.xml b/app/src/main/res/values/strings.xml similarity index 100% rename from res/values/strings.xml rename to app/src/main/res/values/strings.xml diff --git a/res/values/styles.xml b/app/src/main/res/values/styles.xml similarity index 96% rename from res/values/styles.xml rename to app/src/main/res/values/styles.xml index cb035b9..2457908 100644 --- a/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -24,6 +24,8 @@ @color/navigation_bar_bg @bool/light_navigation_bar true + @color/action_bar_background_color + true @@ -66,7 +68,10 @@ @@ -597,7 +604,7 @@ diff --git a/res/values/versions.xml b/app/src/main/res/values/versions.xml similarity index 100% rename from res/values/versions.xml rename to app/src/main/res/values/versions.xml diff --git a/res/xml-mcc204-mnc04/mms_config.xml b/app/src/main/res/xml-mcc204-mnc04/mms_config.xml similarity index 100% rename from res/xml-mcc204-mnc04/mms_config.xml rename to app/src/main/res/xml-mcc204-mnc04/mms_config.xml diff --git a/res/xml-mcc208-mnc01/mms_config.xml b/app/src/main/res/xml-mcc208-mnc01/mms_config.xml similarity index 100% rename from res/xml-mcc208-mnc01/mms_config.xml rename to app/src/main/res/xml-mcc208-mnc01/mms_config.xml diff --git a/res/xml-mcc208-mnc10/mms_config.xml b/app/src/main/res/xml-mcc208-mnc10/mms_config.xml similarity index 100% rename from res/xml-mcc208-mnc10/mms_config.xml rename to app/src/main/res/xml-mcc208-mnc10/mms_config.xml diff --git a/res/xml-mcc208-mnc15/mms_config.xml b/app/src/main/res/xml-mcc208-mnc15/mms_config.xml similarity index 100% rename from res/xml-mcc208-mnc15/mms_config.xml rename to app/src/main/res/xml-mcc208-mnc15/mms_config.xml diff --git a/res/xml-mcc208-mnc20/mms_config.xml b/app/src/main/res/xml-mcc208-mnc20/mms_config.xml similarity index 100% rename from res/xml-mcc208-mnc20/mms_config.xml rename to app/src/main/res/xml-mcc208-mnc20/mms_config.xml diff --git a/res/xml-mcc208-mnc26/mms_config.xml b/app/src/main/res/xml-mcc208-mnc26/mms_config.xml similarity index 100% rename from res/xml-mcc208-mnc26/mms_config.xml rename to app/src/main/res/xml-mcc208-mnc26/mms_config.xml diff --git a/res/xml-mcc214-mnc01/mms_config.xml b/app/src/main/res/xml-mcc214-mnc01/mms_config.xml similarity index 100% rename from res/xml-mcc214-mnc01/mms_config.xml rename to app/src/main/res/xml-mcc214-mnc01/mms_config.xml diff --git a/res/xml-mcc214-mnc03/mms_config.xml b/app/src/main/res/xml-mcc214-mnc03/mms_config.xml similarity index 100% rename from res/xml-mcc214-mnc03/mms_config.xml rename to app/src/main/res/xml-mcc214-mnc03/mms_config.xml diff --git a/res/xml-mcc214-mnc07/mms_config.xml b/app/src/main/res/xml-mcc214-mnc07/mms_config.xml similarity index 100% rename from res/xml-mcc214-mnc07/mms_config.xml rename to app/src/main/res/xml-mcc214-mnc07/mms_config.xml diff --git a/res/xml-mcc218-mnc05/mms_config.xml b/app/src/main/res/xml-mcc218-mnc05/mms_config.xml similarity index 100% rename from res/xml-mcc218-mnc05/mms_config.xml rename to app/src/main/res/xml-mcc218-mnc05/mms_config.xml diff --git a/res/xml-mcc222-mnc01/mms_config.xml b/app/src/main/res/xml-mcc222-mnc01/mms_config.xml similarity index 100% rename from res/xml-mcc222-mnc01/mms_config.xml rename to app/src/main/res/xml-mcc222-mnc01/mms_config.xml diff --git a/res/xml-mcc222-mnc08/mms_config.xml b/app/src/main/res/xml-mcc222-mnc08/mms_config.xml similarity index 100% rename from res/xml-mcc222-mnc08/mms_config.xml rename to app/src/main/res/xml-mcc222-mnc08/mms_config.xml diff --git a/res/xml-mcc234-mnc10/mms_config.xml b/app/src/main/res/xml-mcc234-mnc10/mms_config.xml similarity index 100% rename from res/xml-mcc234-mnc10/mms_config.xml rename to app/src/main/res/xml-mcc234-mnc10/mms_config.xml diff --git a/app/src/main/res/xml-mcc234-mnc11 b/app/src/main/res/xml-mcc234-mnc11 new file mode 100644 index 0000000..e29c9d3 --- /dev/null +++ b/app/src/main/res/xml-mcc234-mnc11 @@ -0,0 +1 @@ +xml-mcc234-mnc10 \ No newline at end of file diff --git a/res/xml-mcc234-mnc15/mms_config.xml b/app/src/main/res/xml-mcc234-mnc15/mms_config.xml similarity index 100% rename from res/xml-mcc234-mnc15/mms_config.xml rename to app/src/main/res/xml-mcc234-mnc15/mms_config.xml diff --git a/res/xml-mcc238-mnc02/mms_config.xml b/app/src/main/res/xml-mcc238-mnc02/mms_config.xml similarity index 100% rename from res/xml-mcc238-mnc02/mms_config.xml rename to app/src/main/res/xml-mcc238-mnc02/mms_config.xml diff --git a/res/xml-mcc240-mnc01/mms_config.xml b/app/src/main/res/xml-mcc240-mnc01/mms_config.xml similarity index 100% rename from res/xml-mcc240-mnc01/mms_config.xml rename to app/src/main/res/xml-mcc240-mnc01/mms_config.xml diff --git a/res/xml-mcc240-mnc04/mms_config.xml b/app/src/main/res/xml-mcc240-mnc04/mms_config.xml similarity index 100% rename from res/xml-mcc240-mnc04/mms_config.xml rename to app/src/main/res/xml-mcc240-mnc04/mms_config.xml diff --git a/res/xml-mcc240-mnc08/mms_config.xml b/app/src/main/res/xml-mcc240-mnc08/mms_config.xml similarity index 100% rename from res/xml-mcc240-mnc08/mms_config.xml rename to app/src/main/res/xml-mcc240-mnc08/mms_config.xml diff --git a/res/xml-mcc240-mnc24/mms_config.xml b/app/src/main/res/xml-mcc240-mnc24/mms_config.xml similarity index 100% rename from res/xml-mcc240-mnc24/mms_config.xml rename to app/src/main/res/xml-mcc240-mnc24/mms_config.xml diff --git a/res/xml-mcc242-mnc01/mms_config.xml b/app/src/main/res/xml-mcc242-mnc01/mms_config.xml similarity index 100% rename from res/xml-mcc242-mnc01/mms_config.xml rename to app/src/main/res/xml-mcc242-mnc01/mms_config.xml diff --git a/res/xml-mcc242-mnc02/mms_config.xml b/app/src/main/res/xml-mcc242-mnc02/mms_config.xml similarity index 100% rename from res/xml-mcc242-mnc02/mms_config.xml rename to app/src/main/res/xml-mcc242-mnc02/mms_config.xml diff --git a/res/xml-mcc262-mnc07/mms_config.xml b/app/src/main/res/xml-mcc262-mnc07/mms_config.xml similarity index 100% rename from res/xml-mcc262-mnc07/mms_config.xml rename to app/src/main/res/xml-mcc262-mnc07/mms_config.xml diff --git a/res/xml-mcc274-mnc02/mms_config.xml b/app/src/main/res/xml-mcc274-mnc02/mms_config.xml similarity index 100% rename from res/xml-mcc274-mnc02/mms_config.xml rename to app/src/main/res/xml-mcc274-mnc02/mms_config.xml diff --git a/res/xml-mcc274-mnc03/mms_config.xml b/app/src/main/res/xml-mcc274-mnc03/mms_config.xml similarity index 100% rename from res/xml-mcc274-mnc03/mms_config.xml rename to app/src/main/res/xml-mcc274-mnc03/mms_config.xml diff --git a/res/xml-mcc286-mnc01/mms_config.xml b/app/src/main/res/xml-mcc286-mnc01/mms_config.xml similarity index 100% rename from res/xml-mcc286-mnc01/mms_config.xml rename to app/src/main/res/xml-mcc286-mnc01/mms_config.xml diff --git a/res/xml-mcc286-mnc03/mms_config.xml b/app/src/main/res/xml-mcc286-mnc03/mms_config.xml similarity index 100% rename from res/xml-mcc286-mnc03/mms_config.xml rename to app/src/main/res/xml-mcc286-mnc03/mms_config.xml diff --git a/res/xml-mcc294-mnc01/mms_config.xml b/app/src/main/res/xml-mcc294-mnc01/mms_config.xml similarity index 100% rename from res/xml-mcc294-mnc01/mms_config.xml rename to app/src/main/res/xml-mcc294-mnc01/mms_config.xml diff --git a/res/xml-mcc294-mnc02/mms_config.xml b/app/src/main/res/xml-mcc294-mnc02/mms_config.xml similarity index 100% rename from res/xml-mcc294-mnc02/mms_config.xml rename to app/src/main/res/xml-mcc294-mnc02/mms_config.xml diff --git a/res/xml-mcc294-mnc03/mms_config.xml b/app/src/main/res/xml-mcc294-mnc03/mms_config.xml similarity index 100% rename from res/xml-mcc294-mnc03/mms_config.xml rename to app/src/main/res/xml-mcc294-mnc03/mms_config.xml diff --git a/res/xml-mcc302-mnc220/mms_config.xml b/app/src/main/res/xml-mcc302-mnc220/mms_config.xml similarity index 100% rename from res/xml-mcc302-mnc220/mms_config.xml rename to app/src/main/res/xml-mcc302-mnc220/mms_config.xml diff --git a/res/xml-mcc302-mnc221/mms_config.xml b/app/src/main/res/xml-mcc302-mnc221/mms_config.xml similarity index 100% rename from res/xml-mcc302-mnc221/mms_config.xml rename to app/src/main/res/xml-mcc302-mnc221/mms_config.xml diff --git a/res/xml-mcc302-mnc270/mms_config.xml b/app/src/main/res/xml-mcc302-mnc270/mms_config.xml similarity index 100% rename from res/xml-mcc302-mnc270/mms_config.xml rename to app/src/main/res/xml-mcc302-mnc270/mms_config.xml diff --git a/res/xml-mcc302-mnc290/mms_config.xml b/app/src/main/res/xml-mcc302-mnc290/mms_config.xml similarity index 100% rename from res/xml-mcc302-mnc290/mms_config.xml rename to app/src/main/res/xml-mcc302-mnc290/mms_config.xml diff --git a/res/xml-mcc302-mnc320/mms_config.xml b/app/src/main/res/xml-mcc302-mnc320/mms_config.xml similarity index 100% rename from res/xml-mcc302-mnc320/mms_config.xml rename to app/src/main/res/xml-mcc302-mnc320/mms_config.xml diff --git a/res/xml-mcc302-mnc370/mms_config.xml b/app/src/main/res/xml-mcc302-mnc370/mms_config.xml similarity index 100% rename from res/xml-mcc302-mnc370/mms_config.xml rename to app/src/main/res/xml-mcc302-mnc370/mms_config.xml diff --git a/res/xml-mcc302-mnc490/mms_config.xml b/app/src/main/res/xml-mcc302-mnc490/mms_config.xml similarity index 100% rename from res/xml-mcc302-mnc490/mms_config.xml rename to app/src/main/res/xml-mcc302-mnc490/mms_config.xml diff --git a/res/xml-mcc302-mnc500/mms_config.xml b/app/src/main/res/xml-mcc302-mnc500/mms_config.xml similarity index 100% rename from res/xml-mcc302-mnc500/mms_config.xml rename to app/src/main/res/xml-mcc302-mnc500/mms_config.xml diff --git a/res/xml-mcc302-mnc510/mms_config.xml b/app/src/main/res/xml-mcc302-mnc510/mms_config.xml similarity index 100% rename from res/xml-mcc302-mnc510/mms_config.xml rename to app/src/main/res/xml-mcc302-mnc510/mms_config.xml diff --git a/res/xml-mcc302-mnc520/mms_config.xml b/app/src/main/res/xml-mcc302-mnc520/mms_config.xml similarity index 100% rename from res/xml-mcc302-mnc520/mms_config.xml rename to app/src/main/res/xml-mcc302-mnc520/mms_config.xml diff --git a/res/xml-mcc302-mnc610/mms_config.xml b/app/src/main/res/xml-mcc302-mnc610/mms_config.xml similarity index 100% rename from res/xml-mcc302-mnc610/mms_config.xml rename to app/src/main/res/xml-mcc302-mnc610/mms_config.xml diff --git a/res/xml-mcc302-mnc660/mms_config.xml b/app/src/main/res/xml-mcc302-mnc660/mms_config.xml similarity index 100% rename from res/xml-mcc302-mnc660/mms_config.xml rename to app/src/main/res/xml-mcc302-mnc660/mms_config.xml diff --git a/res/xml-mcc302-mnc720/mms_config.xml b/app/src/main/res/xml-mcc302-mnc720/mms_config.xml similarity index 100% rename from res/xml-mcc302-mnc720/mms_config.xml rename to app/src/main/res/xml-mcc302-mnc720/mms_config.xml diff --git a/res/xml-mcc302-mnc780/mms_config.xml b/app/src/main/res/xml-mcc302-mnc780/mms_config.xml similarity index 100% rename from res/xml-mcc302-mnc780/mms_config.xml rename to app/src/main/res/xml-mcc302-mnc780/mms_config.xml diff --git a/res/xml-mcc310-mnc004/mms_config.xml b/app/src/main/res/xml-mcc310-mnc004/mms_config.xml similarity index 100% rename from res/xml-mcc310-mnc004/mms_config.xml rename to app/src/main/res/xml-mcc310-mnc004/mms_config.xml diff --git a/res/xml-mcc310-mnc005/mms_config.xml b/app/src/main/res/xml-mcc310-mnc005/mms_config.xml similarity index 100% rename from res/xml-mcc310-mnc005/mms_config.xml rename to app/src/main/res/xml-mcc310-mnc005/mms_config.xml diff --git a/res/xml-mcc310-mnc010/mms_config.xml b/app/src/main/res/xml-mcc310-mnc010/mms_config.xml similarity index 100% rename from res/xml-mcc310-mnc010/mms_config.xml rename to app/src/main/res/xml-mcc310-mnc010/mms_config.xml diff --git a/res/xml-mcc310-mnc026/mms_config.xml b/app/src/main/res/xml-mcc310-mnc026/mms_config.xml similarity index 100% rename from res/xml-mcc310-mnc026/mms_config.xml rename to app/src/main/res/xml-mcc310-mnc026/mms_config.xml diff --git a/res/xml-mcc310-mnc040/mms_config.xml b/app/src/main/res/xml-mcc310-mnc040/mms_config.xml similarity index 100% rename from res/xml-mcc310-mnc040/mms_config.xml rename to app/src/main/res/xml-mcc310-mnc040/mms_config.xml diff --git a/res/xml-mcc310-mnc070/mms_config.xml b/app/src/main/res/xml-mcc310-mnc070/mms_config.xml similarity index 100% rename from res/xml-mcc310-mnc070/mms_config.xml rename to app/src/main/res/xml-mcc310-mnc070/mms_config.xml diff --git a/res/xml-mcc310-mnc090/mms_config.xml b/app/src/main/res/xml-mcc310-mnc090/mms_config.xml similarity index 100% rename from res/xml-mcc310-mnc090/mms_config.xml rename to app/src/main/res/xml-mcc310-mnc090/mms_config.xml diff --git a/res/xml-mcc310-mnc120/mms_config.xml b/app/src/main/res/xml-mcc310-mnc120/mms_config.xml similarity index 100% rename from res/xml-mcc310-mnc120/mms_config.xml rename to app/src/main/res/xml-mcc310-mnc120/mms_config.xml diff --git a/res/xml-mcc310-mnc130/mms_config.xml b/app/src/main/res/xml-mcc310-mnc130/mms_config.xml similarity index 100% rename from res/xml-mcc310-mnc130/mms_config.xml rename to app/src/main/res/xml-mcc310-mnc130/mms_config.xml diff --git a/res/xml-mcc310-mnc150/mms_config.xml b/app/src/main/res/xml-mcc310-mnc150/mms_config.xml similarity index 100% rename from res/xml-mcc310-mnc150/mms_config.xml rename to app/src/main/res/xml-mcc310-mnc150/mms_config.xml diff --git a/res/xml-mcc310-mnc170/mms_config.xml b/app/src/main/res/xml-mcc310-mnc170/mms_config.xml similarity index 100% rename from res/xml-mcc310-mnc170/mms_config.xml rename to app/src/main/res/xml-mcc310-mnc170/mms_config.xml diff --git a/res/xml-mcc310-mnc260/mms_config.xml b/app/src/main/res/xml-mcc310-mnc260/mms_config.xml similarity index 100% rename from res/xml-mcc310-mnc260/mms_config.xml rename to app/src/main/res/xml-mcc310-mnc260/mms_config.xml diff --git a/res/xml-mcc310-mnc360/mms_config.xml b/app/src/main/res/xml-mcc310-mnc360/mms_config.xml similarity index 100% rename from res/xml-mcc310-mnc360/mms_config.xml rename to app/src/main/res/xml-mcc310-mnc360/mms_config.xml diff --git a/res/xml-mcc310-mnc380/mms_config.xml b/app/src/main/res/xml-mcc310-mnc380/mms_config.xml similarity index 100% rename from res/xml-mcc310-mnc380/mms_config.xml rename to app/src/main/res/xml-mcc310-mnc380/mms_config.xml diff --git a/res/xml-mcc310-mnc410/mms_config.xml b/app/src/main/res/xml-mcc310-mnc410/mms_config.xml similarity index 100% rename from res/xml-mcc310-mnc410/mms_config.xml rename to app/src/main/res/xml-mcc310-mnc410/mms_config.xml diff --git a/res/xml-mcc310-mnc420/mms_config.xml b/app/src/main/res/xml-mcc310-mnc420/mms_config.xml similarity index 100% rename from res/xml-mcc310-mnc420/mms_config.xml rename to app/src/main/res/xml-mcc310-mnc420/mms_config.xml diff --git a/res/xml-mcc310-mnc450/mms_config.xml b/app/src/main/res/xml-mcc310-mnc450/mms_config.xml similarity index 100% rename from res/xml-mcc310-mnc450/mms_config.xml rename to app/src/main/res/xml-mcc310-mnc450/mms_config.xml diff --git a/res/xml-mcc310-mnc490/mms_config.xml b/app/src/main/res/xml-mcc310-mnc490/mms_config.xml similarity index 100% rename from res/xml-mcc310-mnc490/mms_config.xml rename to app/src/main/res/xml-mcc310-mnc490/mms_config.xml diff --git a/res/xml-mcc310-mnc560/mms_config.xml b/app/src/main/res/xml-mcc310-mnc560/mms_config.xml similarity index 100% rename from res/xml-mcc310-mnc560/mms_config.xml rename to app/src/main/res/xml-mcc310-mnc560/mms_config.xml diff --git a/res/xml-mcc310-mnc580/mms_config.xml b/app/src/main/res/xml-mcc310-mnc580/mms_config.xml similarity index 100% rename from res/xml-mcc310-mnc580/mms_config.xml rename to app/src/main/res/xml-mcc310-mnc580/mms_config.xml diff --git a/res/xml-mcc310-mnc600/mms_config.xml b/app/src/main/res/xml-mcc310-mnc600/mms_config.xml similarity index 100% rename from res/xml-mcc310-mnc600/mms_config.xml rename to app/src/main/res/xml-mcc310-mnc600/mms_config.xml diff --git a/res/xml-mcc310-mnc680/mms_config.xml b/app/src/main/res/xml-mcc310-mnc680/mms_config.xml similarity index 100% rename from res/xml-mcc310-mnc680/mms_config.xml rename to app/src/main/res/xml-mcc310-mnc680/mms_config.xml diff --git a/res/xml-mcc310-mnc750/mms_config.xml b/app/src/main/res/xml-mcc310-mnc750/mms_config.xml similarity index 100% rename from res/xml-mcc310-mnc750/mms_config.xml rename to app/src/main/res/xml-mcc310-mnc750/mms_config.xml diff --git a/res/xml-mcc310-mnc770/mms_config.xml b/app/src/main/res/xml-mcc310-mnc770/mms_config.xml similarity index 100% rename from res/xml-mcc310-mnc770/mms_config.xml rename to app/src/main/res/xml-mcc310-mnc770/mms_config.xml diff --git a/res/xml-mcc310-mnc920/mms_config.xml b/app/src/main/res/xml-mcc310-mnc920/mms_config.xml similarity index 100% rename from res/xml-mcc310-mnc920/mms_config.xml rename to app/src/main/res/xml-mcc310-mnc920/mms_config.xml diff --git a/res/xml-mcc310-mnc980/mms_config.xml b/app/src/main/res/xml-mcc310-mnc980/mms_config.xml similarity index 100% rename from res/xml-mcc310-mnc980/mms_config.xml rename to app/src/main/res/xml-mcc310-mnc980/mms_config.xml diff --git a/res/xml-mcc311-mnc012/mms_config.xml b/app/src/main/res/xml-mcc311-mnc012/mms_config.xml similarity index 100% rename from res/xml-mcc311-mnc012/mms_config.xml rename to app/src/main/res/xml-mcc311-mnc012/mms_config.xml diff --git a/res/xml-mcc311-mnc070/mms_config.xml b/app/src/main/res/xml-mcc311-mnc070/mms_config.xml similarity index 100% rename from res/xml-mcc311-mnc070/mms_config.xml rename to app/src/main/res/xml-mcc311-mnc070/mms_config.xml diff --git a/res/xml-mcc311-mnc100/mms_config.xml b/app/src/main/res/xml-mcc311-mnc100/mms_config.xml similarity index 100% rename from res/xml-mcc311-mnc100/mms_config.xml rename to app/src/main/res/xml-mcc311-mnc100/mms_config.xml diff --git a/res/xml-mcc311-mnc180/mms_config.xml b/app/src/main/res/xml-mcc311-mnc180/mms_config.xml similarity index 100% rename from res/xml-mcc311-mnc180/mms_config.xml rename to app/src/main/res/xml-mcc311-mnc180/mms_config.xml diff --git a/res/xml-mcc311-mnc220/mms_config.xml b/app/src/main/res/xml-mcc311-mnc220/mms_config.xml similarity index 100% rename from res/xml-mcc311-mnc220/mms_config.xml rename to app/src/main/res/xml-mcc311-mnc220/mms_config.xml diff --git a/res/xml-mcc311-mnc221/mms_config.xml b/app/src/main/res/xml-mcc311-mnc221/mms_config.xml similarity index 100% rename from res/xml-mcc311-mnc221/mms_config.xml rename to app/src/main/res/xml-mcc311-mnc221/mms_config.xml diff --git a/res/xml-mcc311-mnc222/mms_config.xml b/app/src/main/res/xml-mcc311-mnc222/mms_config.xml similarity index 100% rename from res/xml-mcc311-mnc222/mms_config.xml rename to app/src/main/res/xml-mcc311-mnc222/mms_config.xml diff --git a/res/xml-mcc311-mnc223/mms_config.xml b/app/src/main/res/xml-mcc311-mnc223/mms_config.xml similarity index 100% rename from res/xml-mcc311-mnc223/mms_config.xml rename to app/src/main/res/xml-mcc311-mnc223/mms_config.xml diff --git a/res/xml-mcc311-mnc224/mms_config.xml b/app/src/main/res/xml-mcc311-mnc224/mms_config.xml similarity index 100% rename from res/xml-mcc311-mnc224/mms_config.xml rename to app/src/main/res/xml-mcc311-mnc224/mms_config.xml diff --git a/res/xml-mcc311-mnc225/mms_config.xml b/app/src/main/res/xml-mcc311-mnc225/mms_config.xml similarity index 100% rename from res/xml-mcc311-mnc225/mms_config.xml rename to app/src/main/res/xml-mcc311-mnc225/mms_config.xml diff --git a/res/xml-mcc311-mnc226/mms_config.xml b/app/src/main/res/xml-mcc311-mnc226/mms_config.xml similarity index 100% rename from res/xml-mcc311-mnc226/mms_config.xml rename to app/src/main/res/xml-mcc311-mnc226/mms_config.xml diff --git a/res/xml-mcc311-mnc227/mms_config.xml b/app/src/main/res/xml-mcc311-mnc227/mms_config.xml similarity index 100% rename from res/xml-mcc311-mnc227/mms_config.xml rename to app/src/main/res/xml-mcc311-mnc227/mms_config.xml diff --git a/res/xml-mcc311-mnc228/mms_config.xml b/app/src/main/res/xml-mcc311-mnc228/mms_config.xml similarity index 100% rename from res/xml-mcc311-mnc228/mms_config.xml rename to app/src/main/res/xml-mcc311-mnc228/mms_config.xml diff --git a/res/xml-mcc311-mnc229/mms_config.xml b/app/src/main/res/xml-mcc311-mnc229/mms_config.xml similarity index 100% rename from res/xml-mcc311-mnc229/mms_config.xml rename to app/src/main/res/xml-mcc311-mnc229/mms_config.xml diff --git a/res/xml-mcc311-mnc230/mms_config.xml b/app/src/main/res/xml-mcc311-mnc230/mms_config.xml similarity index 100% rename from res/xml-mcc311-mnc230/mms_config.xml rename to app/src/main/res/xml-mcc311-mnc230/mms_config.xml diff --git a/res/xml-mcc311-mnc340/mms_config.xml b/app/src/main/res/xml-mcc311-mnc340/mms_config.xml similarity index 100% rename from res/xml-mcc311-mnc340/mms_config.xml rename to app/src/main/res/xml-mcc311-mnc340/mms_config.xml diff --git a/res/xml-mcc311-mnc370/mms_config.xml b/app/src/main/res/xml-mcc311-mnc370/mms_config.xml similarity index 100% rename from res/xml-mcc311-mnc370/mms_config.xml rename to app/src/main/res/xml-mcc311-mnc370/mms_config.xml diff --git a/res/xml-mcc311-mnc410/mms_config.xml b/app/src/main/res/xml-mcc311-mnc410/mms_config.xml similarity index 100% rename from res/xml-mcc311-mnc410/mms_config.xml rename to app/src/main/res/xml-mcc311-mnc410/mms_config.xml diff --git a/res/xml-mcc311-mnc430/mms_config.xml b/app/src/main/res/xml-mcc311-mnc430/mms_config.xml similarity index 100% rename from res/xml-mcc311-mnc430/mms_config.xml rename to app/src/main/res/xml-mcc311-mnc430/mms_config.xml diff --git a/res/xml-mcc311-mnc440/mms_config.xml b/app/src/main/res/xml-mcc311-mnc440/mms_config.xml similarity index 100% rename from res/xml-mcc311-mnc440/mms_config.xml rename to app/src/main/res/xml-mcc311-mnc440/mms_config.xml diff --git a/res/xml-mcc311-mnc480/mms_config.xml b/app/src/main/res/xml-mcc311-mnc480/mms_config.xml similarity index 100% rename from res/xml-mcc311-mnc480/mms_config.xml rename to app/src/main/res/xml-mcc311-mnc480/mms_config.xml diff --git a/res/xml-mcc311-mnc490/mms_config.xml b/app/src/main/res/xml-mcc311-mnc490/mms_config.xml similarity index 100% rename from res/xml-mcc311-mnc490/mms_config.xml rename to app/src/main/res/xml-mcc311-mnc490/mms_config.xml diff --git a/res/xml-mcc311-mnc580/mms_config.xml b/app/src/main/res/xml-mcc311-mnc580/mms_config.xml similarity index 100% rename from res/xml-mcc311-mnc580/mms_config.xml rename to app/src/main/res/xml-mcc311-mnc580/mms_config.xml diff --git a/res/xml-mcc311-mnc581/mms_config.xml b/app/src/main/res/xml-mcc311-mnc581/mms_config.xml similarity index 100% rename from res/xml-mcc311-mnc581/mms_config.xml rename to app/src/main/res/xml-mcc311-mnc581/mms_config.xml diff --git a/res/xml-mcc311-mnc582/mms_config.xml b/app/src/main/res/xml-mcc311-mnc582/mms_config.xml similarity index 100% rename from res/xml-mcc311-mnc582/mms_config.xml rename to app/src/main/res/xml-mcc311-mnc582/mms_config.xml diff --git a/res/xml-mcc311-mnc583/mms_config.xml b/app/src/main/res/xml-mcc311-mnc583/mms_config.xml similarity index 100% rename from res/xml-mcc311-mnc583/mms_config.xml rename to app/src/main/res/xml-mcc311-mnc583/mms_config.xml diff --git a/res/xml-mcc311-mnc584/mms_config.xml b/app/src/main/res/xml-mcc311-mnc584/mms_config.xml similarity index 100% rename from res/xml-mcc311-mnc584/mms_config.xml rename to app/src/main/res/xml-mcc311-mnc584/mms_config.xml diff --git a/res/xml-mcc311-mnc585/mms_config.xml b/app/src/main/res/xml-mcc311-mnc585/mms_config.xml similarity index 100% rename from res/xml-mcc311-mnc585/mms_config.xml rename to app/src/main/res/xml-mcc311-mnc585/mms_config.xml diff --git a/res/xml-mcc311-mnc586/mms_config.xml b/app/src/main/res/xml-mcc311-mnc586/mms_config.xml similarity index 100% rename from res/xml-mcc311-mnc586/mms_config.xml rename to app/src/main/res/xml-mcc311-mnc586/mms_config.xml diff --git a/res/xml-mcc311-mnc587/mms_config.xml b/app/src/main/res/xml-mcc311-mnc587/mms_config.xml similarity index 100% rename from res/xml-mcc311-mnc587/mms_config.xml rename to app/src/main/res/xml-mcc311-mnc587/mms_config.xml diff --git a/res/xml-mcc311-mnc588/mms_config.xml b/app/src/main/res/xml-mcc311-mnc588/mms_config.xml similarity index 100% rename from res/xml-mcc311-mnc588/mms_config.xml rename to app/src/main/res/xml-mcc311-mnc588/mms_config.xml diff --git a/res/xml-mcc311-mnc589/mms_config.xml b/app/src/main/res/xml-mcc311-mnc589/mms_config.xml similarity index 100% rename from res/xml-mcc311-mnc589/mms_config.xml rename to app/src/main/res/xml-mcc311-mnc589/mms_config.xml diff --git a/res/xml-mcc311-mnc590/mms_config.xml b/app/src/main/res/xml-mcc311-mnc590/mms_config.xml similarity index 100% rename from res/xml-mcc311-mnc590/mms_config.xml rename to app/src/main/res/xml-mcc311-mnc590/mms_config.xml diff --git a/res/xml-mcc311-mnc870/mms_config.xml b/app/src/main/res/xml-mcc311-mnc870/mms_config.xml similarity index 100% rename from res/xml-mcc311-mnc870/mms_config.xml rename to app/src/main/res/xml-mcc311-mnc870/mms_config.xml diff --git a/res/xml-mcc312-mnc160/mms_config.xml b/app/src/main/res/xml-mcc312-mnc160/mms_config.xml similarity index 100% rename from res/xml-mcc312-mnc160/mms_config.xml rename to app/src/main/res/xml-mcc312-mnc160/mms_config.xml diff --git a/res/xml-mcc312-mnc530/mms_config.xml b/app/src/main/res/xml-mcc312-mnc530/mms_config.xml similarity index 100% rename from res/xml-mcc312-mnc530/mms_config.xml rename to app/src/main/res/xml-mcc312-mnc530/mms_config.xml diff --git a/res/xml-mcc334-mnc020/mms_config.xml b/app/src/main/res/xml-mcc334-mnc020/mms_config.xml similarity index 100% rename from res/xml-mcc334-mnc020/mms_config.xml rename to app/src/main/res/xml-mcc334-mnc020/mms_config.xml diff --git a/res/xml-mcc418-mnc05/mms_config.xml b/app/src/main/res/xml-mcc418-mnc05/mms_config.xml similarity index 100% rename from res/xml-mcc418-mnc05/mms_config.xml rename to app/src/main/res/xml-mcc418-mnc05/mms_config.xml diff --git a/res/xml-mcc418-mnc20/mms_config.xml b/app/src/main/res/xml-mcc418-mnc20/mms_config.xml similarity index 100% rename from res/xml-mcc418-mnc20/mms_config.xml rename to app/src/main/res/xml-mcc418-mnc20/mms_config.xml diff --git a/res/xml-mcc418-mnc30/mms_config.xml b/app/src/main/res/xml-mcc418-mnc30/mms_config.xml similarity index 100% rename from res/xml-mcc418-mnc30/mms_config.xml rename to app/src/main/res/xml-mcc418-mnc30/mms_config.xml diff --git a/res/xml-mcc420-mnc04/mms_config.xml b/app/src/main/res/xml-mcc420-mnc04/mms_config.xml similarity index 100% rename from res/xml-mcc420-mnc04/mms_config.xml rename to app/src/main/res/xml-mcc420-mnc04/mms_config.xml diff --git a/res/xml-mcc440-mnc10/mms_config.xml b/app/src/main/res/xml-mcc440-mnc10/mms_config.xml similarity index 100% rename from res/xml-mcc440-mnc10/mms_config.xml rename to app/src/main/res/xml-mcc440-mnc10/mms_config.xml diff --git a/res/xml-mcc440-mnc11/mms_config.xml b/app/src/main/res/xml-mcc440-mnc11/mms_config.xml similarity index 100% rename from res/xml-mcc440-mnc11/mms_config.xml rename to app/src/main/res/xml-mcc440-mnc11/mms_config.xml diff --git a/res/xml-mcc440-mnc20/mms_config.xml b/app/src/main/res/xml-mcc440-mnc20/mms_config.xml similarity index 100% rename from res/xml-mcc440-mnc20/mms_config.xml rename to app/src/main/res/xml-mcc440-mnc20/mms_config.xml diff --git a/res/xml-mcc450-mnc00/mms_config.xml b/app/src/main/res/xml-mcc450-mnc00/mms_config.xml similarity index 100% rename from res/xml-mcc450-mnc00/mms_config.xml rename to app/src/main/res/xml-mcc450-mnc00/mms_config.xml diff --git a/res/xml-mcc450-mnc02/mms_config.xml b/app/src/main/res/xml-mcc450-mnc02/mms_config.xml similarity index 100% rename from res/xml-mcc450-mnc02/mms_config.xml rename to app/src/main/res/xml-mcc450-mnc02/mms_config.xml diff --git a/res/xml-mcc450-mnc05/mms_config.xml b/app/src/main/res/xml-mcc450-mnc05/mms_config.xml similarity index 100% rename from res/xml-mcc450-mnc05/mms_config.xml rename to app/src/main/res/xml-mcc450-mnc05/mms_config.xml diff --git a/res/xml-mcc450-mnc06/mms_config.xml b/app/src/main/res/xml-mcc450-mnc06/mms_config.xml similarity index 100% rename from res/xml-mcc450-mnc06/mms_config.xml rename to app/src/main/res/xml-mcc450-mnc06/mms_config.xml diff --git a/res/xml-mcc450-mnc08/mms_config.xml b/app/src/main/res/xml-mcc450-mnc08/mms_config.xml similarity index 100% rename from res/xml-mcc450-mnc08/mms_config.xml rename to app/src/main/res/xml-mcc450-mnc08/mms_config.xml diff --git a/res/xml-mcc505-mnc01/mms_config.xml b/app/src/main/res/xml-mcc505-mnc01/mms_config.xml similarity index 100% rename from res/xml-mcc505-mnc01/mms_config.xml rename to app/src/main/res/xml-mcc505-mnc01/mms_config.xml diff --git a/res/xml-mcc530-mnc05/mms_config.xml b/app/src/main/res/xml-mcc530-mnc05/mms_config.xml similarity index 100% rename from res/xml-mcc530-mnc05/mms_config.xml rename to app/src/main/res/xml-mcc530-mnc05/mms_config.xml diff --git a/res/xml-mcc604-mnc00/mms_config.xml b/app/src/main/res/xml-mcc604-mnc00/mms_config.xml similarity index 100% rename from res/xml-mcc604-mnc00/mms_config.xml rename to app/src/main/res/xml-mcc604-mnc00/mms_config.xml diff --git a/res/xml-mcc604-mnc02/mms_config.xml b/app/src/main/res/xml-mcc604-mnc02/mms_config.xml similarity index 100% rename from res/xml-mcc604-mnc02/mms_config.xml rename to app/src/main/res/xml-mcc604-mnc02/mms_config.xml diff --git a/res/xml-mcc647-mnc10/mms_config.xml b/app/src/main/res/xml-mcc647-mnc10/mms_config.xml similarity index 100% rename from res/xml-mcc647-mnc10/mms_config.xml rename to app/src/main/res/xml-mcc647-mnc10/mms_config.xml diff --git a/res/xml/mms_config.xml b/app/src/main/res/xml/mms_config.xml similarity index 100% rename from res/xml/mms_config.xml rename to app/src/main/res/xml/mms_config.xml diff --git a/res/xml/preferences_application.xml b/app/src/main/res/xml/preferences_application.xml similarity index 100% rename from res/xml/preferences_application.xml rename to app/src/main/res/xml/preferences_application.xml diff --git a/res/xml/preferences_per_subscription.xml b/app/src/main/res/xml/preferences_per_subscription.xml similarity index 100% rename from res/xml/preferences_per_subscription.xml rename to app/src/main/res/xml/preferences_per_subscription.xml diff --git a/res/xml/widget_conversation.xml b/app/src/main/res/xml/widget_conversation.xml similarity index 100% rename from res/xml/widget_conversation.xml rename to app/src/main/res/xml/widget_conversation.xml diff --git a/res/xml/widget_conversation_list.xml b/app/src/main/res/xml/widget_conversation_list.xml similarity index 100% rename from res/xml/widget_conversation_list.xml rename to app/src/main/res/xml/widget_conversation_list.xml diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000..586a2bb --- /dev/null +++ b/build.gradle @@ -0,0 +1,4 @@ +plugins { + id 'com.android.application' version '8.7.0' apply false + id 'com.android.library' version '8.7.0' apply false +} diff --git a/design/home_nav/automatye.svg b/design/home_nav/automatye.svg new file mode 100644 index 0000000..e236928 --- /dev/null +++ b/design/home_nav/automatye.svg @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/design/home_nav/compose_fab.svg b/design/home_nav/compose_fab.svg new file mode 100644 index 0000000..b26a9ed --- /dev/null +++ b/design/home_nav/compose_fab.svg @@ -0,0 +1,4 @@ + + + + diff --git a/design/home_nav/contact.svg b/design/home_nav/contact.svg new file mode 100644 index 0000000..c815261 --- /dev/null +++ b/design/home_nav/contact.svg @@ -0,0 +1,12 @@ + + + + ic_fluent_contact_card_group_24_filled + Created with Sketch. + + + + + + + \ No newline at end of file diff --git a/design/home_nav/messages.svg b/design/home_nav/messages.svg new file mode 100644 index 0000000..b2cdd8e --- /dev/null +++ b/design/home_nav/messages.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 0000000..14f7eb7 --- /dev/null +++ b/gradle.properties @@ -0,0 +1,8 @@ +org.gradle.jvmargs=-Xmx4096m -Dfile.encoding=UTF-8 +android.useAndroidX=true +android.nonFinalResIds=false + +# This project's dedicated emulator (do not use other AVDs for install/run tasks) +messaging.avd.name=Messaging_Test_API_36.1 +messaging.avd.serial=emulator-5556 +messaging.avd.port=5556 diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..2c35211 Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..19cfad9 --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew new file mode 100644 index 0000000..4568d2c --- /dev/null +++ b/gradlew @@ -0,0 +1,249 @@ +#!/bin/sh + +# +# Copyright © 2015 the original authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# SPDX-License-Identifier: Apache-2.0 +# + +############################################################################## +# +# gradlew start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh gradlew +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/3d91ce3b8caaf77ad09f381f43615b715b53f72c/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# +############################################################################## + +# Attempt to set APP_HOME + +# Resolve links: $0 may be a link +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 0000000..6543977 --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,80 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if %OS%==Windows_NT endlocal + +:omega diff --git a/modules/chips b/modules/chips new file mode 160000 index 0000000..7ccb8ba --- /dev/null +++ b/modules/chips @@ -0,0 +1 @@ +Subproject commit 7ccb8ba59b168d748edfce5030ab6b01226ef393 diff --git a/modules/colorpicker b/modules/colorpicker new file mode 160000 index 0000000..34d5137 --- /dev/null +++ b/modules/colorpicker @@ -0,0 +1 @@ +Subproject commit 34d5137f881a0ffc9f6bb93c5d2e5bbe99265b00 diff --git a/modules/photoviewer b/modules/photoviewer new file mode 160000 index 0000000..fb5c100 --- /dev/null +++ b/modules/photoviewer @@ -0,0 +1 @@ +Subproject commit fb5c100b4a415e69e507962dd6c32660d71dfc66 diff --git a/modules/vcard b/modules/vcard new file mode 160000 index 0000000..f049d8c --- /dev/null +++ b/modules/vcard @@ -0,0 +1 @@ +Subproject commit f049d8cd3a6579d140d22fcdcbdbdfd5f7c020e3 diff --git a/packages_apps_Messaging.code-workspace b/packages_apps_Messaging.code-workspace new file mode 100644 index 0000000..b99677e --- /dev/null +++ b/packages_apps_Messaging.code-workspace @@ -0,0 +1,9 @@ +{ + "folders": [ + { + "name": "packages_apps_Messaging", + "path": "." + } + ], + "settings": {} +} diff --git a/res/layout/contact_picker_fragment.xml b/res/layout/contact_picker_fragment.xml deleted file mode 100644 index ce32a64..0000000 --- a/res/layout/contact_picker_fragment.xml +++ /dev/null @@ -1,80 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/res/layout/conversation_list_fragment.xml b/res/layout/conversation_list_fragment.xml deleted file mode 100644 index d26b55b..0000000 --- a/res/layout/conversation_list_fragment.xml +++ /dev/null @@ -1,55 +0,0 @@ - - - - - - - - - - - diff --git a/res/layout/conversation_list_item_view.xml b/res/layout/conversation_list_item_view.xml deleted file mode 100644 index 382796a..0000000 --- a/res/layout/conversation_list_item_view.xml +++ /dev/null @@ -1,194 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/res/values-night/colors.xml b/res/values-night/colors.xml deleted file mode 100644 index 7056b13..0000000 --- a/res/values-night/colors.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - @android:color/system_neutral1_800 - diff --git a/res/values-night/lineage_bools.xml b/res/values-night/lineage_bools.xml deleted file mode 100644 index 0116948..0000000 --- a/res/values-night/lineage_bools.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - false - diff --git a/res/xml-mcc234-mnc11 b/res/xml-mcc234-mnc11 deleted file mode 120000 index e29c9d3..0000000 --- a/res/xml-mcc234-mnc11 +++ /dev/null @@ -1 +0,0 @@ -xml-mcc234-mnc10 \ No newline at end of file diff --git a/settings.gradle b/settings.gradle new file mode 100644 index 0000000..78cb07c --- /dev/null +++ b/settings.gradle @@ -0,0 +1,23 @@ +pluginManagement { + repositories { + google() + mavenCentral() + gradlePluginPortal() + } +} + +dependencyResolutionManagement { + repositoriesMode.set(RepositoriesMode.PREFER_SETTINGS) + repositories { + google() + mavenCentral() + } +} + +rootProject.name = 'Messaging' + +include ':app' +include ':modules:colorpicker' +include ':modules:chips' +include ':modules:photoviewer' +include ':modules:vcard' diff --git a/src/com/android/messaging/ui/conversationlist/ConversationListAdapter.java b/src/com/android/messaging/ui/conversationlist/ConversationListAdapter.java deleted file mode 100644 index b001925..0000000 --- a/src/com/android/messaging/ui/conversationlist/ConversationListAdapter.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * Copyright (C) 2024 The LineageOS Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.messaging.ui.conversationlist; - -import android.content.Context; -import android.database.Cursor; -import androidx.recyclerview.widget.RecyclerView; -import android.view.LayoutInflater; -import android.view.ViewGroup; - -import com.android.messaging.R; -import com.android.messaging.ui.CursorRecyclerAdapter; - -/** - * Provides an interface to expose Conversation List Cursor data to a UI widget like a ListView. - */ -public class ConversationListAdapter - extends CursorRecyclerAdapter { - - private final ConversationListItemView.HostInterface mClivHostInterface; - - public ConversationListAdapter(final Context context, final Cursor cursor, - final ConversationListItemView.HostInterface clivHostInterface) { - super(context, cursor, 0); - mClivHostInterface = clivHostInterface; - setHasStableIds(true); - } - - /** - * @see com.android.messaging.ui.CursorRecyclerAdapter#bindViewHolder( - * androidx.recyclerview.widget.RecyclerView.ViewHolder, android.content.Context, - * android.database.Cursor) - */ - @Override - public void bindViewHolder(final ConversationListViewHolder holder, final Context context, - final Cursor cursor) { - final ConversationListItemView conversationListItemView = holder.mView; - conversationListItemView.bind(cursor, mClivHostInterface); - } - - @Override - public ConversationListViewHolder createViewHolder(final Context context, - final ViewGroup parent, final int viewType) { - final LayoutInflater layoutInflater = LayoutInflater.from(context); - final ConversationListItemView itemView = - (ConversationListItemView) layoutInflater.inflate( - R.layout.conversation_list_item_view, null); - return new ConversationListViewHolder(itemView); - } - - /** - * ViewHolder that holds a ConversationListItemView. - */ - public static class ConversationListViewHolder extends RecyclerView.ViewHolder { - final ConversationListItemView mView; - - public ConversationListViewHolder(final ConversationListItemView itemView) { - super(itemView); - mView = itemView; - } - } -} diff --git a/src/com/android/messaging/ui/conversationlist/ConversationListFragment.java b/src/com/android/messaging/ui/conversationlist/ConversationListFragment.java deleted file mode 100644 index bfafae0..0000000 --- a/src/com/android/messaging/ui/conversationlist/ConversationListFragment.java +++ /dev/null @@ -1,420 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * Copyright (C) 2024-2025 The LineageOS Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.android.messaging.ui.conversationlist; - -import android.app.Activity; -import android.content.Context; -import android.database.Cursor; -import android.graphics.Rect; -import android.net.Uri; -import android.os.Bundle; -import android.os.Parcelable; -import android.view.LayoutInflater; -import android.view.Menu; -import android.view.MenuInflater; -import android.view.MenuItem; -import android.view.View; -import android.view.ViewGroup; -import android.view.ViewGroup.MarginLayoutParams; -import android.view.ViewPropertyAnimator; -import android.view.accessibility.AccessibilityManager; -import android.widget.AbsListView; - -import androidx.annotation.NonNull; -import androidx.core.view.ViewGroupCompat; -import androidx.fragment.app.Fragment; -import androidx.loader.app.LoaderManager; -import androidx.recyclerview.widget.LinearLayoutManager; -import androidx.recyclerview.widget.RecyclerView; - -import com.android.messaging.R; -import com.android.messaging.datamodel.DataModel; -import com.android.messaging.datamodel.binding.Binding; -import com.android.messaging.datamodel.binding.BindingBase; -import com.android.messaging.datamodel.data.ConversationListData; -import com.android.messaging.datamodel.data.ConversationListData.ConversationListDataListener; -import com.android.messaging.datamodel.data.ConversationListItemData; -import com.android.messaging.ui.ListEmptyView; -import com.android.messaging.ui.SnackBarInteraction; -import com.android.messaging.ui.UIIntents; -import com.android.messaging.util.AccessibilityUtil; -import com.android.messaging.util.ImeUtil; -import com.android.messaging.util.LogUtil; -import com.android.messaging.util.UiUtils; -import com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton; - -import java.util.ArrayList; -import java.util.List; - -/** - * Shows a list of conversations. - */ -public class ConversationListFragment extends Fragment implements ConversationListDataListener, - ConversationListItemView.HostInterface { - private static final String BUNDLE_ARCHIVED_MODE = "archived_mode"; - private static final String BUNDLE_FORWARD_MESSAGE_MODE = "forward_message_mode"; - - private MenuItem mShowBlockedMenuItem; - private boolean mArchiveMode; - private boolean mBlockedAvailable; - private boolean mForwardMessageMode; - - public interface ConversationListFragmentHost { - void onConversationClick(final ConversationListData listData, - final ConversationListItemData conversationListItemData, - final boolean isLongClick, - final ConversationListItemView conversationView); - void onCreateConversationClick(); - boolean isConversationSelected(final String conversationId); - boolean isSwipeAnimatable(); - boolean isSelectionMode(); - boolean hasWindowFocus(); - } - - private ConversationListFragmentHost mHost; - private RecyclerView mRecyclerView; - private ExtendedFloatingActionButton mStartNewConversationButton; - private ListEmptyView mEmptyListMessageView; - private ConversationListAdapter mAdapter; - - // Saved Instance State Data - only for temporal data which is nice to maintain but not - // critical for correctness. - private static final String SAVED_INSTANCE_STATE_LIST_VIEW_STATE_KEY = - "conversationListViewState"; - private Parcelable mListState; - - final Binding mListBinding = BindingBase.createBinding(this); - - public static ConversationListFragment createArchivedConversationListFragment() { - return createConversationListFragment(BUNDLE_ARCHIVED_MODE); - } - - public static ConversationListFragment createForwardMessageConversationListFragment() { - return createConversationListFragment(BUNDLE_FORWARD_MESSAGE_MODE); - } - - public static ConversationListFragment createConversationListFragment(String modeKeyName) { - final ConversationListFragment fragment = new ConversationListFragment(); - if (modeKeyName != null) { - final Bundle bundle = new Bundle(); - bundle.putBoolean(modeKeyName, true); - fragment.setArguments(bundle); - } - return fragment; - } - - /** - * {@inheritDoc} from Fragment - */ - @Override - public void onCreate(final Bundle bundle) { - super.onCreate(bundle); - mListBinding.getData().init(LoaderManager.getInstance(this), mListBinding); - mAdapter = new ConversationListAdapter(getActivity(), null, this); - } - - @Override - public void onResume() { - super.onResume(); - - mHost = (ConversationListFragmentHost) getActivity(); - setScrolledToNewestConversationIfNeeded(); - - updateUi(); - } - - public void setScrolledToNewestConversationIfNeeded() { - if (!mArchiveMode - && !mForwardMessageMode - && isScrolledToFirstConversation() - && mHost.hasWindowFocus()) { - mListBinding.getData().setScrolledToNewestConversation(true); - } - } - - private boolean isScrolledToFirstConversation() { - int firstItemPosition = ((LinearLayoutManager) mRecyclerView.getLayoutManager()) - .findFirstCompletelyVisibleItemPosition(); - return firstItemPosition == 0; - } - - /** - * {@inheritDoc} from Fragment - */ - @Override - public void onDestroy() { - super.onDestroy(); - mListBinding.unbind(); - mHost = null; - } - - /** - * {@inheritDoc} from Fragment - */ - @Override - public View onCreateView(final LayoutInflater inflater, final ViewGroup container, - final Bundle savedInstanceState) { - final ViewGroup rootView = (ViewGroup) inflater.inflate(R.layout.conversation_list_fragment, - container, false); - mRecyclerView = rootView.findViewById(android.R.id.list); - mEmptyListMessageView = rootView.findViewById(R.id.no_conversations_view); - mEmptyListMessageView.setImageHint(R.drawable.ic_oobe_conv_list); - // The default behavior for default layout param generation by LinearLayoutManager is to - // provide width and height of WRAP_CONTENT, but this is not desirable for - // ConversationListFragment; the view in each row should be a width of MATCH_PARENT so that - // the entire row is tappable. - final Activity activity = getActivity(); - final LinearLayoutManager manager = new LinearLayoutManager(activity) { - @Override - public RecyclerView.LayoutParams generateDefaultLayoutParams() { - return new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, - ViewGroup.LayoutParams.WRAP_CONTENT); - } - }; - mRecyclerView.setLayoutManager(manager); - mRecyclerView.setHasFixedSize(true); - mRecyclerView.setAdapter(mAdapter); - mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { - int mCurrentState = AbsListView.OnScrollListener.SCROLL_STATE_IDLE; - - @Override - public void onScrolled(@NonNull final RecyclerView recyclerView, final int dx, - final int dy) { - if (mCurrentState == AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL - || mCurrentState == AbsListView.OnScrollListener.SCROLL_STATE_FLING) { - ImeUtil.get().hideImeKeyboard(getActivity(), mRecyclerView); - } - - if (isScrolledToFirstConversation()) { - setScrolledToNewestConversationIfNeeded(); - } else { - mListBinding.getData().setScrolledToNewestConversation(false); - } - } - - @Override - public void onScrollStateChanged(@NonNull final RecyclerView recyclerView, - final int newState) { - mCurrentState = newState; - } - }); - mRecyclerView.addOnItemTouchListener(new ConversationListSwipeHelper(mRecyclerView)); - - if (savedInstanceState != null) { - mListState = savedInstanceState.getParcelable(SAVED_INSTANCE_STATE_LIST_VIEW_STATE_KEY, - Parcelable.class); - } - - mStartNewConversationButton = rootView.findViewById(R.id.start_new_conversation_button); - if (mArchiveMode || mForwardMessageMode) { - mStartNewConversationButton.setVisibility(View.GONE); - } else { - mStartNewConversationButton.setVisibility(View.VISIBLE); - mStartNewConversationButton.setOnClickListener(clickView -> - mHost.onCreateConversationClick()); - } - - // The root view has a non-null background, which by default is deemed by the framework - // to be a "transition group," where all child views are animated together during an - // activity transition. However, we want each individual items in the recycler view to - // show explode animation themselves, so we explicitly tag the root view to be a non-group. - ViewGroupCompat.setTransitionGroup(rootView, false); - - setHasOptionsMenu(true); - return rootView; - } - - @Override - public void onAttach(@NonNull final Context context) { - super.onAttach(context); - LogUtil.v(LogUtil.BUGLE_TAG, "Attaching List"); - final Bundle arguments = getArguments(); - if (arguments != null) { - mArchiveMode = arguments.getBoolean(BUNDLE_ARCHIVED_MODE, false); - mForwardMessageMode = arguments.getBoolean(BUNDLE_FORWARD_MESSAGE_MODE, false); - } - mListBinding.bind(DataModel.get().createConversationListData(context, this, mArchiveMode)); - } - - - @Override - public void onSaveInstanceState(@NonNull final Bundle outState) { - super.onSaveInstanceState(outState); - if (mListState != null) { - outState.putParcelable(SAVED_INSTANCE_STATE_LIST_VIEW_STATE_KEY, mListState); - } - } - - @Override - public void onPause() { - super.onPause(); - mListState = mRecyclerView.getLayoutManager().onSaveInstanceState(); - mListBinding.getData().setScrolledToNewestConversation(false); - } - - @Override - public void onConversationListCursorUpdated(final ConversationListData data, - final Cursor cursor) { - mListBinding.ensureBound(data); - final Cursor oldCursor = mAdapter.swapCursor(cursor); - updateEmptyListUi(cursor == null || cursor.getCount() == 0); - if (mListState != null && cursor != null && oldCursor == null) { - mRecyclerView.getLayoutManager().onRestoreInstanceState(mListState); - } - } - - @Override - public void setBlockedParticipantsAvailable(final boolean blockedAvailable) { - mBlockedAvailable = blockedAvailable; - if (mShowBlockedMenuItem != null) { - mShowBlockedMenuItem.setVisible(blockedAvailable); - } - } - - public void updateUi() { - mAdapter.notifyDataSetChanged(); - } - - @Override - public void onPrepareOptionsMenu(@NonNull final Menu menu) { - super.onPrepareOptionsMenu(menu); - final MenuItem startNewConversationMenuItem = - menu.findItem(R.id.action_start_new_conversation); - if (startNewConversationMenuItem != null) { - // It is recommended for the Floating Action button functionality to be duplicated as a - // menu - AccessibilityManager accessibilityManager = (AccessibilityManager) - requireActivity().getSystemService(Context.ACCESSIBILITY_SERVICE); - startNewConversationMenuItem.setVisible(accessibilityManager - .isTouchExplorationEnabled()); - } - - final MenuItem archive = menu.findItem(R.id.action_show_archived); - if (archive != null) { - archive.setVisible(true); - } - } - - @Override - public void onCreateOptionsMenu(@NonNull final Menu menu, - @NonNull final MenuInflater inflater) { - if (!isAdded()) { - // Guard against being called before we're added to the activity - return; - } - - mShowBlockedMenuItem = menu.findItem(R.id.action_show_blocked_contacts); - if (mShowBlockedMenuItem != null) { - mShowBlockedMenuItem.setVisible(mBlockedAvailable); - } - } - - /** - * {@inheritDoc} from ConversationListItemView.HostInterface - */ - @Override - public void onConversationClicked(final ConversationListItemData conversationListItemData, - final boolean isLongClick, final ConversationListItemView conversationView) { - final ConversationListData listData = mListBinding.getData(); - mHost.onConversationClick(listData, conversationListItemData, isLongClick, - conversationView); - } - - /** - * {@inheritDoc} from ConversationListItemView.HostInterface - */ - @Override - public boolean isConversationSelected(final String conversationId) { - return mHost.isConversationSelected(conversationId); - } - - @Override - public boolean isSwipeAnimatable() { - return mHost.isSwipeAnimatable(); - } - - // Show and hide empty list UI as needed with appropriate text based on view specifics - private void updateEmptyListUi(final boolean isEmpty) { - if (isEmpty) { - int emptyListText; - if (!mListBinding.getData().getHasFirstSyncCompleted()) { - emptyListText = R.string.conversation_list_first_sync_text; - } else if (mArchiveMode) { - emptyListText = R.string.archived_conversation_list_empty_text; - } else { - emptyListText = R.string.conversation_list_empty_text; - } - mEmptyListMessageView.setTextHint(emptyListText); - mEmptyListMessageView.setVisibility(View.VISIBLE); - mEmptyListMessageView.setIsImageVisible(true); - mEmptyListMessageView.setIsVerticallyCentered(true); - } else { - mEmptyListMessageView.setVisibility(View.GONE); - } - } - - @Override - public List getSnackBarInteractions() { - final List interactions = new ArrayList<>(1); - final SnackBarInteraction fabInteraction = - new SnackBarInteraction.BasicSnackBarInteraction(mStartNewConversationButton); - interactions.add(fabInteraction); - return interactions; - } - - private ViewPropertyAnimator getNormalizedFabAnimator() { - return mStartNewConversationButton.animate() - .setInterpolator(UiUtils.DEFAULT_INTERPOLATOR) - .setDuration(getActivity().getResources().getInteger( - R.integer.fab_animation_duration_ms)); - } - - public void dismissFab() { - // To prevent clicking while animating. - mStartNewConversationButton.setEnabled(false); - final MarginLayoutParams lp = - (MarginLayoutParams) mStartNewConversationButton.getLayoutParams(); - final float fabWidthWithLeftRightMargin = mStartNewConversationButton.getWidth() - + lp.leftMargin + lp.rightMargin; - final int direction = AccessibilityUtil.isLayoutRtl(mStartNewConversationButton) ? -1 : 1; - getNormalizedFabAnimator().translationX(direction * fabWidthWithLeftRightMargin); - } - - public void showFab() { - getNormalizedFabAnimator().translationX(0).withEndAction(() -> { - // Re-enable clicks after the animation. - mStartNewConversationButton.setEnabled(true); - }); - } - - @Override - public void startFullScreenPhotoViewer( - final Uri initialPhoto, final Rect initialPhotoBounds, final Uri photosUri) { - UIIntents.get().launchFullScreenPhotoViewer( - getActivity(), initialPhoto, initialPhotoBounds, photosUri); - } - - @Override - public void startFullScreenVideoViewer(final Uri videoUri) { - UIIntents.get().launchFullScreenVideoViewer(getActivity(), videoUri); - } - - @Override - public boolean isSelectionMode() { - return mHost != null && mHost.isSelectionMode(); - } -} diff --git a/tools/looply_applied.png b/tools/looply_applied.png new file mode 100644 index 0000000..33c2c6b Binary files /dev/null and b/tools/looply_applied.png differ diff --git a/tools/seed_contacts.sh b/tools/seed_contacts.sh new file mode 100644 index 0000000..be31409 --- /dev/null +++ b/tools/seed_contacts.sh @@ -0,0 +1,54 @@ +#!/system/bin/sh +# Seed contacts for Messaging demo (run on device via adb shell) + +add_contact() { + name="$1" + phone="$2" + content insert --uri content://com.android.contacts/raw_contacts \ + --bind account_type:s:com.android.local \ + --bind account_name:s:Phone >/dev/null + raw=$(content query --uri content://com.android.contacts/raw_contacts \ + --projection _id --sort '_id DESC' | head -n1 | sed 's/.*_id=//') + if [ -z "$raw" ]; then + echo "FAIL $name" + return 1 + fi + content insert --uri content://com.android.contacts/data \ + --bind raw_contact_id:i:$raw \ + --bind mimetype:s:vnd.android.cursor.item/name \ + --bind data1:s:"$name" >/dev/null + content insert --uri content://com.android.contacts/data \ + --bind raw_contact_id:i:$raw \ + --bind mimetype:s:vnd.android.cursor.item/phone_v2 \ + --bind data1:s:"$phone" \ + --bind data2:i:2 >/dev/null + echo "OK $name raw=$raw" +} + +add_contact "Sarah Jenkins" "+15551230001" +add_contact "Product Design" "+15551230002" +add_contact "David Chen" "+15551230003" +add_contact "Marcus Knight" "+15551230004" +add_contact "Priya Patel" "+15551230005" +add_contact "Alex Rivera" "+15551230006" +add_contact "Jordan Lee" "+15551230007" +add_contact "Mom" "+15551230008" +add_contact "Cafe Nova" "+15551230009" +add_contact "Bank Alerts" "+15551230010" +add_contact "Nina Okonkwo" "+15551230011" +add_contact "Chris Park" "+15551230012" +add_contact "Emily Watson" "+15551230013" +add_contact "Support Desk" "+15551230014" +add_contact "Leo Martinez" "+15551230015" +add_contact "Hannah Kim" "+15551230016" +add_contact "Delivery" "+15551230017" +add_contact "Sam Torres" "+15551230018" +add_contact "Auto Bot" "+15551230019" +add_contact "Riley Quinn" "+15551230020" +add_contact "Dr Patel" "+15551230021" +add_contact "Gym Club" "+15551230022" +add_contact "Mia Chen" "+15551230023" +add_contact "Owen Brooks" "+15551230024" + +echo "CONTACTS:" +content query --uri content://com.android.contacts/contacts --projection display_name diff --git a/tools/seed_demo_data.ps1 b/tools/seed_demo_data.ps1 new file mode 100644 index 0000000..129cfbf --- /dev/null +++ b/tools/seed_demo_data.ps1 @@ -0,0 +1,85 @@ +# Seed demo contacts + SMS for Messaging UI preview (emulator-5556) +# Usage: powershell -ExecutionPolicy Bypass -File tools/seed_demo_data.ps1 +$ErrorActionPreference = "Continue" +$sdk = "$env:LOCALAPPDATA\Android\Sdk" +$adb = Join-Path $sdk "platform-tools\adb.exe" +$serial = "emulator-5556" + +function Invoke-Adb { + param([Parameter(ValueFromRemainingArguments = $true)][string[]]$CmdArgs) + & $adb -s $serial @CmdArgs +} + +Write-Host "== Default SMS + permissions ==" +Invoke-Adb shell cmd role add-role-holder android.app.role.SMS com.android.messaging | Out-Null +Invoke-Adb shell settings put secure sms_default_application com.android.messaging | Out-Null +foreach ($p in @( + "READ_SMS","RECEIVE_SMS","SEND_SMS","RECEIVE_MMS", + "READ_CONTACTS","WRITE_CONTACTS","READ_PHONE_STATE", + "READ_PHONE_NUMBERS","POST_NOTIFICATIONS" +)) { + Invoke-Adb shell pm grant com.android.messaging "android.permission.$p" 2>$null | Out-Null +} + +$demo = @( + @{ Name = "Sarah Jenkins"; Phone = "+15551230001"; Msgs = @("Can you review the Looply mock before standup?","Also dropped the Figma link.","Morning! Coffee run in 10?") } + @{ Name = "Product Design"; Phone = "+15551230002"; Msgs = @("Team sync moved to 3pm.","New icon set is ready for QA.") } + @{ Name = "David Chen"; Phone = "+15551230003"; Msgs = @("On my way - traffic near Market St.","Got the package. Thanks!") } + @{ Name = "Marcus Knight"; Phone = "+15551230004"; Msgs = @("Ship checklist looks good. Ship it.","Need one more screenshot.") } + @{ Name = "Priya Patel"; Phone = "+15551230005"; Msgs = @("Unread reminder: invoice 4821 waiting.","Ping me when you are free.") } + @{ Name = "Alex Rivera"; Phone = "+15551230006"; Msgs = @("Weekend hike still on?","Bring extra water.") } + @{ Name = "Jordan Lee"; Phone = "+15551230007"; Msgs = @("Draft PR for home chips is up.","Can you take a look before EOD?") } + @{ Name = "Mom"; Phone = "+15551230008"; Msgs = @("Call me when you land.","Love you!") } + @{ Name = "Cafe Nova"; Phone = "+15551230009"; Msgs = @("Your order is ready for pickup.","Table for 2 confirmed at 7:30.") } + @{ Name = "Bank Alerts"; Phone = "+15551230010"; Msgs = @("Purchase of 42.18 at LOOPLY MARKET.","Your statement is available.") } + @{ Name = "Nina Okonkwo"; Phone = "+15551230011"; Msgs = @("Shared the brand tokens doc.","Purple 5A31F4 is locked.") } + @{ Name = "Chris Park"; Phone = "+15551230012"; Msgs = @("Gym at 6?","Bring the resistance bands.") } + @{ Name = "Emily Watson"; Phone = "+15551230013"; Msgs = @("Flight delayed 40 min.","See you at baggage claim.") } + @{ Name = "Support Desk"; Phone = "+15551230014"; Msgs = @("Ticket 9021 resolved. Reply STOP to opt out.","We received your request.") } + @{ Name = "Leo Martinez"; Phone = "+15551230015"; Msgs = @("Game night Friday?","I will bring snacks.") } + @{ Name = "Hannah Kim"; Phone = "+15551230016"; Msgs = @("Updated the contacts card layout.","Looks much closer to Message+.") } + @{ Name = "Delivery"; Phone = "+15551230017"; Msgs = @("Driver is 3 stops away.","Pin: leave at door.") } + @{ Name = "Sam Torres"; Phone = "+15551230018"; Msgs = @("Lunch tomorrow?","That new ramen place.") } + @{ Name = "Auto Bot"; Phone = "+15551230019"; Msgs = @("Automation rule ran successfully.","3 messages routed to Archives.") } + @{ Name = "Riley Quinn"; Phone = "+15551230020"; Msgs = @("Photo from the rooftop attached concept.","Cant wait for launch week!") } + @{ Name = "Dr Patel"; Phone = "+15551230021"; Msgs = @("Appointment confirmed for Tue 10:30am.","Reply C to confirm.") } + @{ Name = "Gym Club"; Phone = "+15551230022"; Msgs = @("Class starts in 20 minutes.","Membership renews next month.") } + @{ Name = "Mia Chen"; Phone = "+15551230023"; Msgs = @("Sent the locale strings.","KO EN both look good.") } + @{ Name = "Owen Brooks"; Phone = "+15551230024"; Msgs = @("Parking is full - use lot B.","See you inside.") } +) + +Write-Host "== Contacts ($($demo.Count)) ==" +foreach ($c in $demo) { + Invoke-Adb shell "content insert --uri content://com.android.contacts/raw_contacts --bind account_type:s:com.android.local --bind account_name:s:Phone" | Out-Null + $row = (Invoke-Adb shell "content query --uri content://com.android.contacts/raw_contacts --projection _id --sort '_id DESC'") | Select-Object -First 1 + if ($row -match "_id=(\d+)") { + $id = $Matches[1] + Invoke-Adb shell "content insert --uri content://com.android.contacts/data --bind raw_contact_id:i:$id --bind mimetype:s:vnd.android.cursor.item/name --bind data1:s:'$($c.Name)'" | Out-Null + Invoke-Adb shell "content insert --uri content://com.android.contacts/data --bind raw_contact_id:i:$id --bind mimetype:s:vnd.android.cursor.item/phone_v2 --bind data1:s:$($c.Phone) --bind data2:i:2" | Out-Null + Write-Host " + $($c.Name)" + } +} + +Write-Host "== SMS threads ==" +$sends = 0 +foreach ($c in $demo) { + for ($i = $c.Msgs.Count - 1; $i -ge 0; $i--) { + Invoke-Adb emu sms send $c.Phone $c.Msgs[$i] | Out-Null + $sends++ + Start-Sleep -Milliseconds 120 + } + Write-Host " thread $($c.Name)" +} +Write-Host " sends=$sends" + +Write-Host "== Mark half read ==" +for ($i = 0; $i -lt $demo.Count; $i += 2) { + $phone = $demo[$i].Phone + Invoke-Adb shell "content update --uri content://sms --bind read:i:1 --bind seen:i:1 --where `"address='$phone'`"" | Out-Null +} + +Write-Host "== Relaunch ==" +Invoke-Adb shell am force-stop com.android.messaging | Out-Null +Start-Sleep -Seconds 1 +Invoke-Adb shell am start -n com.android.messaging/.ui.conversationlist.ConversationListActivity | Out-Null +Write-Host "Done."