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 @@
+
+
\ 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."