├── .gitignore ├── LICENSE.txt ├── README.md ├── android-text-manager ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── xlythe │ │ └── textmanager │ │ └── text │ │ └── ParcelableTest.java │ └── main │ ├── AndroidManifest.xml │ └── java │ └── com │ └── xlythe │ └── textmanager │ ├── Attachment.java │ ├── Message.java │ ├── MessageCallback.java │ ├── MessageManager.java │ ├── MessageObserver.java │ ├── MessageThread.java │ ├── Status.java │ ├── User.java │ └── text │ ├── Attachment.java │ ├── Contact.java │ ├── ImageAttachment.java │ ├── MmsReceiveService.java │ ├── Mock.java │ ├── NetworkUtils.java │ ├── Receive.java │ ├── SendService.java │ ├── Status.java │ ├── Text.java │ ├── TextManager.java │ ├── TextReceiver.java │ ├── Thread.java │ ├── VideoAttachment.java │ ├── VoiceAttachment.java │ ├── concurrency │ ├── Future.java │ ├── FutureImpl.java │ └── Present.java │ ├── exception │ └── MmsException.java │ ├── pdu │ ├── AcknowledgeInd.java │ ├── DeliveryInd.java │ ├── GenericPdu.java │ ├── MultimediaMessagePdu.java │ ├── NotificationInd.java │ ├── NotifyRespInd.java │ ├── PduBody.java │ ├── PduCache.java │ ├── PduCacheEntry.java │ ├── PduComposer.java │ ├── PduContentTypes.java │ ├── PduHeaders.java │ ├── PduParser.java │ ├── PduPart.java │ ├── PduPersister.java │ ├── QuotedPrintable.java │ ├── ReadOrigInd.java │ ├── ReadRecInd.java │ ├── RetrieveConf.java │ ├── SendConf.java │ └── SendReq.java │ ├── receiver │ ├── MmsReceiver.java │ └── SmsReceiver.java │ ├── service │ └── HeadlessSmsSendService.java │ ├── smil │ ├── AttrImpl.java │ ├── DocumentEvent.java │ ├── DocumentImpl.java │ ├── ElementImpl.java │ ├── ElementLayout.java │ ├── ElementParallelTimeContainer.java │ ├── ElementParallelTimeContainerImpl.java │ ├── ElementSequentialTimeContainer.java │ ├── ElementSequentialTimeContainerImpl.java │ ├── ElementTime.java │ ├── ElementTimeContainer.java │ ├── ElementTimeContainerImpl.java │ ├── ElementTimeImpl.java │ ├── Event.java │ ├── EventException.java │ ├── EventImpl.java │ ├── EventListener.java │ ├── EventTarget.java │ ├── EventTargetImpl.java │ ├── HVGALayoutParameters.java │ ├── LayoutManager.java │ ├── LayoutParameters.java │ ├── NamedNodeMapImpl.java │ ├── NodeImpl.java │ ├── NodeListImpl.java │ ├── SMILDocument.java │ ├── SMILElement.java │ ├── SMILLayoutElement.java │ ├── SMILMediaElement.java │ ├── SMILParElement.java │ ├── SMILRefElement.java │ ├── SMILRegionElement.java │ ├── SMILRegionInterface.java │ ├── SMILRegionMediaElement.java │ ├── SMILRootLayoutElement.java │ ├── SmilDocumentImpl.java │ ├── SmilElementImpl.java │ ├── SmilHelper.java │ ├── SmilLayoutElementImpl.java │ ├── SmilMediaElementImpl.java │ ├── SmilParElementImpl.java │ ├── SmilRefElementImpl.java │ ├── SmilRegionElementImpl.java │ ├── SmilRegionMediaElementImpl.java │ ├── SmilRootLayoutElementImpl.java │ ├── SmilXmlSerializer.java │ ├── Time.java │ ├── TimeImpl.java │ ├── TimeList.java │ └── TimeListImpl.java │ └── util │ ├── AbstractCache.java │ ├── AndroidHttpClient.java │ ├── ApnDefaults.java │ ├── Base64.java │ ├── CharacterSets.java │ ├── ContentType.java │ ├── DownloadDrmHelper.java │ ├── Downloads.java │ ├── DrmConvertSession.java │ ├── EncodedStringValue.java │ ├── HttpDateTime.java │ ├── HttpUtils.java │ ├── MessageUtils.java │ ├── PreKitKatUtils.java │ ├── ProgressCallbackEntity.java │ └── Utils.java ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── main │ ├── AndroidManifest.xml │ ├── ic_launcher-web.png │ ├── java │ │ └── com │ │ │ └── xlythe │ │ │ └── sms │ │ │ ├── ComposeActivity.java │ │ │ ├── ContactSearchActivity.java │ │ │ ├── InfoActivity.java │ │ │ ├── MainActivity.java │ │ │ ├── MediaActivity.java │ │ │ ├── MessageActivity.java │ │ │ ├── ShareMediaActivity.java │ │ │ ├── adapter │ │ │ ├── AttachmentAdapter.java │ │ │ ├── ContactAdapter.java │ │ │ ├── ContactIconAdapter.java │ │ │ ├── MessageAdapter.java │ │ │ ├── MessageAttachmentAdapter.java │ │ │ ├── SelectableAdapter.java │ │ │ ├── ShareMediaAdapter.java │ │ │ ├── StickerAdapter.java │ │ │ └── ThreadAdapter.java │ │ │ ├── decoration │ │ │ ├── DividerItemDecoration.java │ │ │ ├── GalleryItemDecoration.java │ │ │ ├── HeadersDecoration.java │ │ │ └── ThreadsItemDecoration.java │ │ │ ├── drawable │ │ │ ├── ExtendedProfileDrawable.java │ │ │ └── ProfileDrawable.java │ │ │ ├── fragment │ │ │ ├── CameraFragment.java │ │ │ ├── GalleryFragment.java │ │ │ ├── LocationFragment.java │ │ │ ├── MicFragment.java │ │ │ └── StickerFragment.java │ │ │ ├── pojo │ │ │ └── Sticker.java │ │ │ ├── receiver │ │ │ └── MessageReceiver.java │ │ │ ├── service │ │ │ └── FetchChooserTargetService.java │ │ │ ├── util │ │ │ ├── ArrayUtils.java │ │ │ ├── BitmapUtils.java │ │ │ ├── ColorUtils.java │ │ │ ├── DateFormatter.java │ │ │ ├── PermissionUtils.java │ │ │ └── ShortcutUtils.java │ │ │ └── view │ │ │ ├── ContactEditText.java │ │ │ ├── PreviewDialog.java │ │ │ └── SquareImageView.java │ └── res │ │ ├── drawable-hdpi │ │ ├── back_mic.png │ │ ├── camera.png │ │ ├── camera_back.png │ │ ├── camera_front.png │ │ ├── checked.png │ │ ├── checked_icon.png │ │ ├── circle.png │ │ ├── face.png │ │ ├── fetch_icon_notif.png │ │ ├── ic_back.png │ │ ├── ic_copy.png │ │ ├── ic_info.png │ │ ├── ic_message.png │ │ ├── ic_pause.png │ │ ├── ic_play.png │ │ ├── ic_profile.png │ │ ├── ic_search.png │ │ ├── ic_send.png │ │ ├── ic_share.png │ │ ├── ic_trash.png │ │ ├── mic.png │ │ ├── mic_rec.png │ │ ├── photo.png │ │ ├── ring.png │ │ ├── send_mms_bottom.png │ │ ├── send_mms_button.png │ │ ├── send_mms_top.png │ │ ├── thumb_affection.png │ │ ├── thumb_approval.png │ │ ├── thumb_confused.png │ │ ├── thumb_crying.png │ │ ├── thumb_depressed.png │ │ ├── thumb_elated.png │ │ ├── thumb_embarrassed.png │ │ ├── thumb_excited.png │ │ ├── thumb_failure.png │ │ ├── thumb_killme.png │ │ ├── thumb_lazyass.png │ │ ├── thumb_love.png │ │ ├── thumb_nicksface.png │ │ ├── thumb_noproblem.png │ │ ├── thumb_pat.png │ │ ├── thumb_pets.png │ │ ├── thumb_pout.png │ │ ├── thumb_praiseme.png │ │ ├── thumb_puppydog.png │ │ ├── thumb_seansface.png │ │ ├── thumb_shocked.png │ │ ├── thumb_shy.png │ │ ├── thumb_stressed.png │ │ ├── thumb_suspicious.png │ │ ├── thumb_thinking.png │ │ ├── thumb_unmotivated.png │ │ ├── unchecked.png │ │ └── video.png │ │ ├── drawable-ldrtl-xxxhdpi │ │ ├── ic_send.png │ │ ├── left_bottom.9.png │ │ ├── left_middle.9.png │ │ ├── left_single.9.png │ │ ├── left_top.9.png │ │ ├── right_bottom.9.png │ │ ├── right_middle.9.png │ │ ├── right_single.9.png │ │ └── right_top.9.png │ │ ├── drawable-mdpi │ │ ├── back_mic.png │ │ ├── camera.png │ │ ├── camera_back.png │ │ ├── camera_front.png │ │ ├── checked.png │ │ ├── checked_icon.png │ │ ├── circle.png │ │ ├── face.png │ │ ├── fetch_icon_notif.png │ │ ├── ic_copy.png │ │ ├── ic_info.png │ │ ├── ic_message.png │ │ ├── ic_pause.png │ │ ├── ic_play.png │ │ ├── ic_profile.png │ │ ├── ic_search.png │ │ ├── ic_send.png │ │ ├── ic_share.png │ │ ├── ic_trash.png │ │ ├── mic.png │ │ ├── mic_rec.png │ │ ├── photo.png │ │ ├── ring.png │ │ ├── send_mms_bottom.png │ │ ├── send_mms_button.png │ │ ├── send_mms_top.png │ │ ├── thumb_affection.png │ │ ├── thumb_approval.png │ │ ├── thumb_confused.png │ │ ├── thumb_crying.png │ │ ├── thumb_depressed.png │ │ ├── thumb_elated.png │ │ ├── thumb_embarrassed.png │ │ ├── thumb_excited.png │ │ ├── thumb_failure.png │ │ ├── thumb_killme.png │ │ ├── thumb_lazyass.png │ │ ├── thumb_love.png │ │ ├── thumb_nicksface.png │ │ ├── thumb_noproblem.png │ │ ├── thumb_pat.png │ │ ├── thumb_pets.png │ │ ├── thumb_pout.png │ │ ├── thumb_praiseme.png │ │ ├── thumb_puppydog.png │ │ ├── thumb_seansface.png │ │ ├── thumb_shocked.png │ │ ├── thumb_shy.png │ │ ├── thumb_stressed.png │ │ ├── thumb_suspicious.png │ │ ├── thumb_thinking.png │ │ ├── thumb_unmotivated.png │ │ ├── unchecked.png │ │ └── video.png │ │ ├── drawable-xhdpi │ │ ├── back_mic.png │ │ ├── camera.png │ │ ├── camera_back.png │ │ ├── camera_front.png │ │ ├── checked.png │ │ ├── checked_icon.png │ │ ├── circle.png │ │ ├── face.png │ │ ├── fetch_icon_notif.png │ │ ├── ic_copy.png │ │ ├── ic_info.png │ │ ├── ic_message.png │ │ ├── ic_pause.png │ │ ├── ic_play.png │ │ ├── ic_profile.png │ │ ├── ic_search.png │ │ ├── ic_send.png │ │ ├── ic_share.png │ │ ├── ic_trash.png │ │ ├── mic.png │ │ ├── mic_rec.png │ │ ├── photo.png │ │ ├── ring.png │ │ ├── send_mms_bottom.png │ │ ├── send_mms_button.png │ │ ├── send_mms_top.png │ │ ├── thumb_affection.png │ │ ├── thumb_approval.png │ │ ├── thumb_confused.png │ │ ├── thumb_crying.png │ │ ├── thumb_depressed.png │ │ ├── thumb_elated.png │ │ ├── thumb_embarrassed.png │ │ ├── thumb_excited.png │ │ ├── thumb_failure.png │ │ ├── thumb_killme.png │ │ ├── thumb_lazyass.png │ │ ├── thumb_love.png │ │ ├── thumb_nicksface.png │ │ ├── thumb_noproblem.png │ │ ├── thumb_pat.png │ │ ├── thumb_pets.png │ │ ├── thumb_pout.png │ │ ├── thumb_praiseme.png │ │ ├── thumb_puppydog.png │ │ ├── thumb_seansface.png │ │ ├── thumb_shocked.png │ │ ├── thumb_shy.png │ │ ├── thumb_stressed.png │ │ ├── thumb_suspicious.png │ │ ├── thumb_thinking.png │ │ ├── thumb_unmotivated.png │ │ ├── unchecked.png │ │ └── video.png │ │ ├── drawable-xxhdpi │ │ ├── back_mic.png │ │ ├── camera.png │ │ ├── camera_back.png │ │ ├── camera_front.png │ │ ├── checked.png │ │ ├── checked_icon.png │ │ ├── circle.png │ │ ├── face.png │ │ ├── fetch_icon_notif.png │ │ ├── ic_copy.png │ │ ├── ic_info.png │ │ ├── ic_message.png │ │ ├── ic_pause.png │ │ ├── ic_play.png │ │ ├── ic_profile.png │ │ ├── ic_search.png │ │ ├── ic_send.png │ │ ├── ic_share.png │ │ ├── ic_trash.png │ │ ├── mic.png │ │ ├── mic_rec.png │ │ ├── photo.png │ │ ├── ring.png │ │ ├── send_mms_bottom.png │ │ ├── send_mms_button.png │ │ ├── send_mms_top.png │ │ ├── thumb_affection.png │ │ ├── thumb_approval.png │ │ ├── thumb_confused.png │ │ ├── thumb_crying.png │ │ ├── thumb_depressed.png │ │ ├── thumb_elated.png │ │ ├── thumb_embarrassed.png │ │ ├── thumb_excited.png │ │ ├── thumb_failure.png │ │ ├── thumb_killme.png │ │ ├── thumb_lazyass.png │ │ ├── thumb_love.png │ │ ├── thumb_nicksface.png │ │ ├── thumb_noproblem.png │ │ ├── thumb_pat.png │ │ ├── thumb_pets.png │ │ ├── thumb_pout.png │ │ ├── thumb_praiseme.png │ │ ├── thumb_puppydog.png │ │ ├── thumb_seansface.png │ │ ├── thumb_shocked.png │ │ ├── thumb_shy.png │ │ ├── thumb_stressed.png │ │ ├── thumb_suspicious.png │ │ ├── thumb_thinking.png │ │ ├── thumb_unmotivated.png │ │ ├── unchecked.png │ │ └── video.png │ │ ├── drawable-xxxhdpi │ │ ├── back_mic.png │ │ ├── btn_record.png │ │ ├── btn_record_press.png │ │ ├── camera.png │ │ ├── camera_back.png │ │ ├── camera_front.png │ │ ├── checked.png │ │ ├── checked_icon.png │ │ ├── circle.png │ │ ├── divider.9.png │ │ ├── empty.png │ │ ├── empty_background.png │ │ ├── face.png │ │ ├── fakeshadow.9.png │ │ ├── fetch_icon_notif.png │ │ ├── highlight.9.png │ │ ├── ic_copy.png │ │ ├── ic_info.png │ │ ├── ic_message.png │ │ ├── ic_pause.png │ │ ├── ic_play.png │ │ ├── ic_profile.png │ │ ├── ic_search.png │ │ ├── ic_send.png │ │ ├── ic_share.png │ │ ├── ic_trash.png │ │ ├── left_bottom.9.png │ │ ├── left_middle.9.png │ │ ├── left_single.9.png │ │ ├── left_top.9.png │ │ ├── mic.png │ │ ├── mic_rec.png │ │ ├── photo.png │ │ ├── right_bottom.9.png │ │ ├── right_middle.9.png │ │ ├── right_single.9.png │ │ ├── right_top.9.png │ │ ├── ring.png │ │ ├── send_mms_bottom.png │ │ ├── send_mms_button.png │ │ ├── send_mms_top.png │ │ ├── thumb_affection.png │ │ ├── thumb_approval.png │ │ ├── thumb_confused.png │ │ ├── thumb_crying.png │ │ ├── thumb_depressed.png │ │ ├── thumb_elated.png │ │ ├── thumb_embarrassed.png │ │ ├── thumb_excited.png │ │ ├── thumb_failure.png │ │ ├── thumb_killme.png │ │ ├── thumb_lazyass.png │ │ ├── thumb_love.png │ │ ├── thumb_nicksface.png │ │ ├── thumb_noproblem.png │ │ ├── thumb_pat.png │ │ ├── thumb_pets.png │ │ ├── thumb_pout.png │ │ ├── thumb_praiseme.png │ │ ├── thumb_puppydog.png │ │ ├── thumb_seansface.png │ │ ├── thumb_shocked.png │ │ ├── thumb_shy.png │ │ ├── thumb_stressed.png │ │ ├── thumb_suspicious.png │ │ ├── thumb_thinking.png │ │ ├── thumb_unmotivated.png │ │ ├── unchecked.png │ │ └── video.png │ │ ├── drawable │ │ ├── border.xml │ │ ├── camera_switcher.xml │ │ ├── capture.xml │ │ ├── divider_attach.xml │ │ ├── divider_compose.xml │ │ ├── ic_launcher_background.xml │ │ ├── preview_bg.xml │ │ ├── progress_drawable.xml │ │ ├── progress_record.xml │ │ └── selector.xml │ │ ├── layout │ │ ├── activity_compose.xml │ │ ├── activity_contact_search.xml │ │ ├── activity_info.xml │ │ ├── activity_main.xml │ │ ├── activity_media.xml │ │ ├── activity_message.xml │ │ ├── activity_share_media.xml │ │ ├── attach_icon.xml │ │ ├── content_compose.xml │ │ ├── content_main.xml │ │ ├── content_message.xml │ │ ├── content_permission_error.xml │ │ ├── dialog_sticker_preview.xml │ │ ├── fragment_camera.xml │ │ ├── fragment_gallery.xml │ │ ├── fragment_location.xml │ │ ├── fragment_mic.xml │ │ ├── fragment_sticker.xml │ │ ├── grid_item_sticker.xml │ │ ├── info_stub.xml │ │ ├── left_attachment_bottom.xml │ │ ├── left_attachment_middle.xml │ │ ├── left_attachment_single.xml │ │ ├── left_attachment_top.xml │ │ ├── left_bottom.xml │ │ ├── left_middle.xml │ │ ├── left_single.xml │ │ ├── left_top.xml │ │ ├── list_item.xml │ │ ├── list_item_attachment.xml │ │ ├── list_item_contact.xml │ │ ├── list_item_contact_icon.xml │ │ ├── list_item_message_attachment.xml │ │ ├── list_item_share_media.xml │ │ ├── right_attachment_bottom.xml │ │ ├── right_attachment_middle.xml │ │ ├── right_attachment_single.xml │ │ ├── right_attachment_top.xml │ │ ├── right_bottom.xml │ │ ├── right_middle.xml │ │ ├── right_single.xml │ │ ├── right_top.xml │ │ └── section.xml │ │ ├── menu │ │ ├── menu_compose.xml │ │ ├── menu_main.xml │ │ ├── menu_message.xml │ │ ├── menu_messages.xml │ │ ├── menu_share_media.xml │ │ └── selected_menu.xml │ │ ├── mipmap-anydpi-v26 │ │ ├── ic_launcher.xml │ │ └── ic_launcher_round.xml │ │ ├── mipmap-hdpi │ │ ├── ic_launcher.png │ │ ├── ic_launcher_foreground.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-mdpi │ │ ├── ic_launcher.png │ │ ├── ic_launcher_foreground.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xhdpi │ │ ├── ic_launcher.png │ │ ├── ic_launcher_foreground.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.png │ │ ├── ic_launcher_foreground.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.png │ │ ├── ic_launcher_foreground.png │ │ └── ic_launcher_round.png │ │ ├── raw │ │ ├── stickers_affection.png │ │ ├── stickers_approval.png │ │ ├── stickers_confused.png │ │ ├── stickers_crying.png │ │ ├── stickers_depressed.png │ │ ├── stickers_elated.png │ │ ├── stickers_embarrassed.png │ │ ├── stickers_excited.png │ │ ├── stickers_failure.png │ │ ├── stickers_killme.png │ │ ├── stickers_lazyass.png │ │ ├── stickers_love.png │ │ ├── stickers_nicksface.png │ │ ├── stickers_noproblem.png │ │ ├── stickers_pat.png │ │ ├── stickers_pets.png │ │ ├── stickers_pout.png │ │ ├── stickers_praiseme.png │ │ ├── stickers_puppydog.png │ │ ├── stickers_seansface.png │ │ ├── stickers_shocked.png │ │ ├── stickers_shy.png │ │ ├── stickers_stressed.png │ │ ├── stickers_suspicious.png │ │ ├── stickers_thinking.png │ │ └── stickers_unmotivated.png │ │ ├── transition │ │ └── window_slide.xml │ │ ├── values-v21 │ │ ├── dimens.xml │ │ └── styles.xml │ │ ├── values-w820dp │ │ └── dimens.xml │ │ └── values │ │ ├── attrs.xml │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── ic_launcher_background.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ ├── com │ └── xlythe │ │ ├── sms │ │ ├── receiver │ │ │ └── NotificationsTest.java │ │ └── view │ │ │ └── ContactEditTextTest.java │ │ └── textmanager │ │ └── text │ │ ├── ShadowContact.java │ │ └── ShadowTextManager.java │ └── javax │ └── microedition │ └── khronos │ └── opengles │ └── GL.java ├── build.gradle ├── gradle.properties └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | .gradle 2 | /local.properties 3 | /.idea/workspace.xml 4 | /.idea/libraries 5 | .DS_Store 6 | /build 7 | /.idea 8 | *.iml 9 | /gradle 10 | gradlew 11 | gradlew.bat 12 | *.apk 13 | app/release/output-metadata.json 14 | -------------------------------------------------------------------------------- /android-text-manager/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /android-text-manager/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in C:\Users\Will\Downloads\adt-bundle-windows-x86_64-20140624\sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /android-text-manager/src/main/java/com/xlythe/textmanager/Attachment.java: -------------------------------------------------------------------------------- 1 | package com.xlythe.textmanager; 2 | 3 | /** 4 | * Represents images, videos, voice. 5 | */ 6 | public interface Attachment { 7 | 8 | } 9 | -------------------------------------------------------------------------------- /android-text-manager/src/main/java/com/xlythe/textmanager/Message.java: -------------------------------------------------------------------------------- 1 | package com.xlythe.textmanager; 2 | 3 | import com.xlythe.textmanager.text.Attachment; 4 | import com.xlythe.textmanager.text.Status; 5 | 6 | /** 7 | * Represents a message. May contain attachments like images, voice. 8 | */ 9 | public interface Message { 10 | String getId(); 11 | String getThreadId(); 12 | String getBody(); 13 | long getTimestamp(); 14 | Attachment getAttachment(); 15 | Status getStatus(); // Status.Sending, Status.Sent, Status.Failed, Status.Read, Status.Unread 16 | } 17 | -------------------------------------------------------------------------------- /android-text-manager/src/main/java/com/xlythe/textmanager/MessageCallback.java: -------------------------------------------------------------------------------- 1 | package com.xlythe.textmanager; 2 | 3 | /** 4 | * Used for delayed retrieval of messages 5 | */ 6 | public interface MessageCallback { 7 | /** 8 | * The operation was successful 9 | * */ 10 | void onSuccess(T t); 11 | 12 | /** 13 | * An error occurred. 14 | * */ 15 | void onFailure(Exception e); 16 | } 17 | -------------------------------------------------------------------------------- /android-text-manager/src/main/java/com/xlythe/textmanager/MessageManager.java: -------------------------------------------------------------------------------- 1 | package com.xlythe.textmanager; 2 | 3 | import android.database.Cursor; 4 | 5 | import com.xlythe.textmanager.text.concurrency.Future; 6 | 7 | import java.util.List; 8 | import java.util.Set; 9 | 10 | /** 11 | * A generic interface for managing messages 12 | */ 13 | public interface MessageManager { 14 | 15 | /** 16 | * Returns all messages for the given thread 17 | */ 18 | Future> getMessages(T thread); 19 | 20 | /** 21 | * Returns a message cursor for the given thread 22 | */ 23 | Cursor getMessageCursor(T thread); 24 | 25 | /** 26 | * Returns a message given an id 27 | */ 28 | Future getMessage(String id); 29 | 30 | /** 31 | * Return all threads 32 | */ 33 | Future> getThreads(); 34 | 35 | /** 36 | * Returns a thread cursor 37 | */ 38 | Cursor getThreadCursor(); 39 | 40 | /** 41 | * Returns a thread given an id 42 | */ 43 | Future getThread(String id); 44 | 45 | /** 46 | * Deletes a message 47 | */ 48 | void delete(M... message); 49 | 50 | /** 51 | * Deletes a thread 52 | */ 53 | void delete(T... thread); 54 | 55 | /** 56 | * Marks a message as read 57 | */ 58 | void markAsRead(M message); 59 | 60 | /** 61 | * Marks all messages in a thread as read 62 | */ 63 | void markAsRead(T thread); 64 | 65 | /** 66 | * Return all messages containing the text. 67 | */ 68 | Future> search(String text); 69 | 70 | /** 71 | * Register an observer to get callbacks every time messages are added, deleted, or changed. 72 | */ 73 | void registerObserver(MessageObserver observer); 74 | 75 | /** 76 | * Remove a registered observer 77 | */ 78 | void unregisterObserver(MessageObserver observer); 79 | 80 | int getUnreadCount(T thread); 81 | int getCount(T thread); 82 | Future getSender(M message); 83 | Future> getMembers(M message); 84 | } 85 | -------------------------------------------------------------------------------- /android-text-manager/src/main/java/com/xlythe/textmanager/MessageObserver.java: -------------------------------------------------------------------------------- 1 | package com.xlythe.textmanager; 2 | 3 | /** 4 | * Will notify you whenever messages are changed. 5 | */ 6 | public interface MessageObserver { 7 | /** 8 | * There has been a change, and you need to refresh the ui. 9 | * */ 10 | void notifyDataChanged(); 11 | } 12 | -------------------------------------------------------------------------------- /android-text-manager/src/main/java/com/xlythe/textmanager/MessageThread.java: -------------------------------------------------------------------------------- 1 | package com.xlythe.textmanager; 2 | 3 | /** 4 | * Represents a series of messages. 5 | * 6 | * This is a conversation (Like a chain of emails). 7 | */ 8 | public interface MessageThread { 9 | String getId(); 10 | M getLatestMessage(); 11 | } 12 | -------------------------------------------------------------------------------- /android-text-manager/src/main/java/com/xlythe/textmanager/Status.java: -------------------------------------------------------------------------------- 1 | package com.xlythe.textmanager; 2 | 3 | /** 4 | * Created by Niko on 12/31/15. 5 | */ 6 | public interface Status { 7 | } 8 | -------------------------------------------------------------------------------- /android-text-manager/src/main/java/com/xlythe/textmanager/User.java: -------------------------------------------------------------------------------- 1 | package com.xlythe.textmanager; 2 | 3 | import android.net.Uri; 4 | 5 | /** 6 | * Represents a person who can send or receive messages. 7 | */ 8 | public interface User { 9 | String getDisplayName(); 10 | Uri getPhotoUri(); 11 | } 12 | -------------------------------------------------------------------------------- /android-text-manager/src/main/java/com/xlythe/textmanager/text/Status.java: -------------------------------------------------------------------------------- 1 | package com.xlythe.textmanager.text; 2 | 3 | /** 4 | * Created by Niko on 12/29/15. 5 | */ 6 | public enum Status { 7 | COMPLETE, PENDING, FAILED, NONE 8 | } 9 | -------------------------------------------------------------------------------- /android-text-manager/src/main/java/com/xlythe/textmanager/text/VideoAttachment.java: -------------------------------------------------------------------------------- 1 | package com.xlythe.textmanager.text; 2 | 3 | import android.content.Context; 4 | import android.net.Uri; 5 | import android.os.Parcel; 6 | import android.os.Parcelable; 7 | import android.util.Log; 8 | 9 | import com.xlythe.textmanager.text.concurrency.Future; 10 | import com.xlythe.textmanager.text.concurrency.FutureImpl; 11 | import com.xlythe.textmanager.text.concurrency.Present; 12 | 13 | import java.io.IOException; 14 | 15 | import static com.xlythe.textmanager.text.TextManager.TAG; 16 | 17 | public final class VideoAttachment extends Attachment { 18 | private transient byte[] mBytes; 19 | 20 | public VideoAttachment(Uri uri){ 21 | super(Type.VIDEO, uri); 22 | } 23 | 24 | private VideoAttachment(Parcel in) { 25 | super(in); 26 | } 27 | 28 | public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { 29 | public VideoAttachment createFromParcel(Parcel in) { 30 | return new VideoAttachment(in); 31 | } 32 | 33 | public VideoAttachment[] newArray(int size) { 34 | return new VideoAttachment[size]; 35 | } 36 | }; 37 | 38 | public synchronized Future getBytes(final Context context) { 39 | if (mBytes != null) { 40 | return new Present<>(mBytes); 41 | } else { 42 | return new FutureImpl() { 43 | @Override 44 | public byte[] get() { 45 | try { 46 | mBytes = toBytes(asStream(context)); 47 | } catch (IOException e) { 48 | Log.e(TAG, "Failed to decode " + getUri() + " as bytes"); 49 | } 50 | return mBytes; 51 | } 52 | }; 53 | } 54 | } 55 | 56 | private synchronized void setBytes(byte[] bytes) { 57 | mBytes = bytes; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /android-text-manager/src/main/java/com/xlythe/textmanager/text/VoiceAttachment.java: -------------------------------------------------------------------------------- 1 | package com.xlythe.textmanager.text; 2 | 3 | import android.net.Uri; 4 | import android.os.Parcel; 5 | import android.os.Parcelable; 6 | 7 | public final class VoiceAttachment extends Attachment { 8 | public VoiceAttachment(Uri uri){ 9 | super(Type.VOICE, uri); 10 | } 11 | 12 | private VoiceAttachment(Parcel in) { 13 | super(in); 14 | } 15 | 16 | public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { 17 | public VoiceAttachment createFromParcel(Parcel in) { 18 | return new VoiceAttachment(in); 19 | } 20 | 21 | public VoiceAttachment[] newArray(int size) { 22 | return new VoiceAttachment[size]; 23 | } 24 | }; 25 | } 26 | -------------------------------------------------------------------------------- /android-text-manager/src/main/java/com/xlythe/textmanager/text/concurrency/Future.java: -------------------------------------------------------------------------------- 1 | package com.xlythe.textmanager.text.concurrency; 2 | 3 | /** 4 | * Represents a variable that may or may not have been loaded yet. Text, Thread, and Contact 5 | * have their data spread out over several databases and so not all of their variables may have 6 | * been initialized. 7 | */ 8 | public interface Future { 9 | /** 10 | * Returns the value with a blocking call. 11 | */ 12 | T get(); 13 | 14 | /** 15 | * Returns the value some time in the future. 16 | */ 17 | void get(Future.Callback callback); 18 | 19 | /** 20 | * A callback for once the value has loaded. 21 | */ 22 | interface Callback { 23 | void get(T instance); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /android-text-manager/src/main/java/com/xlythe/textmanager/text/concurrency/FutureImpl.java: -------------------------------------------------------------------------------- 1 | package com.xlythe.textmanager.text.concurrency; 2 | 3 | import android.os.Handler; 4 | import android.os.Looper; 5 | 6 | import androidx.annotation.NonNull; 7 | 8 | import java.util.concurrent.ExecutorService; 9 | import java.util.concurrent.Executors; 10 | 11 | /** 12 | * Represents a variable that needs to be loaded. 13 | */ 14 | public abstract class FutureImpl implements Future { 15 | private static final ExecutorService sExecutorService = Executors.newSingleThreadExecutor(); 16 | 17 | // This handler posts to the thread it's created on. 18 | private final Handler mForegroundHandler; 19 | 20 | public FutureImpl() { 21 | if (Looper.myLooper() != null) { 22 | mForegroundHandler = new Handler(); 23 | } else { 24 | mForegroundHandler = null; 25 | } 26 | } 27 | 28 | @Override 29 | public void get(Callback callback) { 30 | sExecutorService.submit(() -> { 31 | // We got the result, but we're still on the background thread. 32 | T result = get(); 33 | 34 | // If we know how to, post to get back to the calling thread. 35 | if (mForegroundHandler != null) { 36 | mForegroundHandler.post(() -> callback.get(result)); 37 | } else { 38 | // Otherwise, return from our background thread. 39 | callback.get(result); 40 | } 41 | }); 42 | } 43 | 44 | @NonNull 45 | @Override 46 | public String toString() { 47 | return get().toString(); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /android-text-manager/src/main/java/com/xlythe/textmanager/text/concurrency/Present.java: -------------------------------------------------------------------------------- 1 | package com.xlythe.textmanager.text.concurrency; 2 | 3 | import androidx.annotation.NonNull; 4 | 5 | /** 6 | * Represents a variable that has already been loaded. 7 | */ 8 | public class Present implements Future { 9 | private final T mInstance; 10 | 11 | public Present(T instance) { 12 | mInstance = instance; 13 | } 14 | 15 | @Override 16 | public T get() { 17 | return mInstance; 18 | } 19 | 20 | @Override 21 | public void get(Future.Callback callback) { 22 | callback.get(mInstance); 23 | } 24 | 25 | @NonNull 26 | @Override 27 | public String toString() { 28 | return get().toString(); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /android-text-manager/src/main/java/com/xlythe/textmanager/text/exception/MmsException.java: -------------------------------------------------------------------------------- 1 | package com.xlythe.textmanager.text.exception; 2 | 3 | public class MmsException extends Exception { 4 | /** 5 | * Creates a new MmsException. 6 | */ 7 | public MmsException() { 8 | super(); 9 | } 10 | 11 | /** 12 | * Creates a new MmsException with the specified detail message. 13 | * 14 | * @param message the detail message. 15 | */ 16 | public MmsException(String message) { 17 | super(message); 18 | } 19 | 20 | /** 21 | * Creates a new MmsException with the specified cause. 22 | * 23 | * @param cause the cause. 24 | */ 25 | public MmsException(Throwable cause) { 26 | super(cause); 27 | } 28 | 29 | /** 30 | * Creates a new MmsException with the specified detail message and cause. 31 | * 32 | * @param message the detail message. 33 | * @param cause the cause. 34 | */ 35 | public MmsException(String message, Throwable cause) { 36 | super(message, cause); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /android-text-manager/src/main/java/com/xlythe/textmanager/text/pdu/PduCacheEntry.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2008 Esmertec AG. 3 | * Copyright (C) 2008 The Android Open Source Project 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package com.xlythe.textmanager.text.pdu; 19 | 20 | public final class PduCacheEntry { 21 | private final GenericPdu mPdu; 22 | private final int mMessageBox; 23 | private final long mThreadId; 24 | 25 | public PduCacheEntry(GenericPdu pdu, int msgBox, long threadId) { 26 | mPdu = pdu; 27 | mMessageBox = msgBox; 28 | mThreadId = threadId; 29 | } 30 | 31 | public GenericPdu getPdu() { 32 | return mPdu; 33 | } 34 | 35 | public int getMessageBox() { 36 | return mMessageBox; 37 | } 38 | 39 | public long getThreadId() { 40 | return mThreadId; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /android-text-manager/src/main/java/com/xlythe/textmanager/text/pdu/QuotedPrintable.java: -------------------------------------------------------------------------------- 1 | package com.xlythe.textmanager.text.pdu; 2 | 3 | import java.io.ByteArrayOutputStream; 4 | 5 | public class QuotedPrintable { 6 | private static final byte ESCAPE_CHAR = '='; 7 | 8 | /** 9 | * Decodes an array quoted-printable characters into an array of original bytes. 10 | * Escaped characters are converted back to their original representation. 11 | * 12 | *

13 | * This function implements a subset of 14 | * quoted-printable encoding specification (rule #1 and rule #2) 15 | * as defined in RFC 1521. 16 | *

17 | * 18 | * @param bytes array of quoted-printable characters 19 | * @return array of original bytes, 20 | * null if quoted-printable decoding is unsuccessful. 21 | */ 22 | public static byte[] decodeQuotedPrintable(byte[] bytes) { 23 | if (bytes == null) { 24 | return null; 25 | } 26 | ByteArrayOutputStream buffer = new ByteArrayOutputStream(); 27 | for (int i = 0; i < bytes.length; i++) { 28 | int b = bytes[i]; 29 | if (b == ESCAPE_CHAR) { 30 | try { 31 | if('\r' == (char)bytes[i + 1] && 32 | '\n' == (char)bytes[i + 2]) { 33 | i += 2; 34 | continue; 35 | } 36 | int u = Character.digit((char) bytes[++i], 16); 37 | int l = Character.digit((char) bytes[++i], 16); 38 | if (u == -1 || l == -1) { 39 | return null; 40 | } 41 | buffer.write((char) ((u << 4) + l)); 42 | } catch (ArrayIndexOutOfBoundsException e) { 43 | return null; 44 | } 45 | } else { 46 | buffer.write(b); 47 | } 48 | } 49 | return buffer.toByteArray(); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /android-text-manager/src/main/java/com/xlythe/textmanager/text/receiver/MmsReceiver.java: -------------------------------------------------------------------------------- 1 | package com.xlythe.textmanager.text.receiver; 2 | 3 | import android.content.Context; 4 | import android.content.Intent; 5 | 6 | import com.xlythe.textmanager.text.Text; 7 | import com.xlythe.textmanager.text.TextReceiver; 8 | 9 | public class MmsReceiver extends TextReceiver { 10 | @Override 11 | public void onMessageReceived(Context context, Text text) { 12 | Intent intent = new Intent(ACTION_TEXT_RECEIVED); 13 | intent.setPackage(context.getPackageName()); 14 | intent.putExtra(EXTRA_TEXT, text); 15 | context.sendBroadcast(intent); 16 | } 17 | } -------------------------------------------------------------------------------- /android-text-manager/src/main/java/com/xlythe/textmanager/text/receiver/SmsReceiver.java: -------------------------------------------------------------------------------- 1 | package com.xlythe.textmanager.text.receiver; 2 | 3 | import android.content.Context; 4 | import android.content.Intent; 5 | 6 | import com.xlythe.textmanager.text.Text; 7 | import com.xlythe.textmanager.text.TextReceiver; 8 | 9 | public class SmsReceiver extends TextReceiver { 10 | @Override 11 | public void onMessageReceived(Context context, Text text) { 12 | Intent intent = new Intent(ACTION_TEXT_RECEIVED); 13 | intent.setPackage(context.getPackageName()); 14 | intent.putExtra(EXTRA_TEXT, text); 15 | context.sendBroadcast(intent); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /android-text-manager/src/main/java/com/xlythe/textmanager/text/service/HeadlessSmsSendService.java: -------------------------------------------------------------------------------- 1 | package com.xlythe.textmanager.text.service; 2 | 3 | import android.app.IntentService; 4 | import android.content.Intent; 5 | import android.telephony.TelephonyManager; 6 | 7 | import com.xlythe.textmanager.text.Text; 8 | import com.xlythe.textmanager.text.TextManager; 9 | import com.xlythe.textmanager.text.util.MessageUtils; 10 | 11 | public class HeadlessSmsSendService extends IntentService { 12 | 13 | public HeadlessSmsSendService() { 14 | super(HeadlessSmsSendService.class.getSimpleName()); 15 | setIntentRedelivery(true); 16 | } 17 | 18 | @Override 19 | protected void onHandleIntent(Intent intent) { 20 | String action = intent.getAction(); 21 | if (!TelephonyManager.ACTION_RESPOND_VIA_MESSAGE.equals(action)) { 22 | return; 23 | } 24 | 25 | Text text = MessageUtils.parse(this, intent); 26 | if (text != null) { 27 | TextManager.getInstance(this).send(text); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /android-text-manager/src/main/java/com/xlythe/textmanager/text/smil/AttrImpl.java: -------------------------------------------------------------------------------- 1 | package com.xlythe.textmanager.text.smil; 2 | 3 | import org.w3c.dom.Attr; 4 | import org.w3c.dom.DOMException; 5 | import org.w3c.dom.Element; 6 | import org.w3c.dom.Node; 7 | import org.w3c.dom.TypeInfo; 8 | 9 | public class AttrImpl extends NodeImpl implements Attr { 10 | private final String mName; 11 | private String mValue; 12 | 13 | /* 14 | * Internal methods 15 | */ 16 | 17 | protected AttrImpl(DocumentImpl owner, String name) { 18 | super(owner); 19 | mName = name; 20 | } 21 | 22 | /* 23 | * Attr Interface Methods 24 | */ 25 | 26 | public String getName() { 27 | return mName; 28 | } 29 | 30 | public Element getOwnerElement() { 31 | // TODO Auto-generated method stub 32 | return null; 33 | } 34 | 35 | public boolean getSpecified() { 36 | return mValue != null; 37 | } 38 | 39 | public String getValue() { 40 | return mValue; 41 | } 42 | 43 | // Instead of setting a Text> with the content of the 44 | // String value as defined in the specs, we directly set here the 45 | // internal mValue member. 46 | public void setValue(String value) throws DOMException { 47 | mValue = value; 48 | } 49 | 50 | /* 51 | * Node Interface Methods 52 | */ 53 | 54 | @Override 55 | public String getNodeName() { 56 | return mName; 57 | } 58 | 59 | @Override 60 | public short getNodeType() { 61 | return Node.ATTRIBUTE_NODE; 62 | } 63 | 64 | @Override 65 | public Node getParentNode() { 66 | return null; 67 | } 68 | 69 | @Override 70 | public Node getPreviousSibling() { 71 | return null; 72 | } 73 | 74 | @Override 75 | public Node getNextSibling() { 76 | return null; 77 | } 78 | 79 | @Override 80 | public void setNodeValue(String nodeValue) throws DOMException { 81 | setValue(nodeValue); 82 | } 83 | 84 | public TypeInfo getSchemaTypeInfo() { 85 | return null; 86 | } 87 | 88 | public boolean isId() { 89 | return false; 90 | } 91 | } -------------------------------------------------------------------------------- /android-text-manager/src/main/java/com/xlythe/textmanager/text/smil/DocumentEvent.java: -------------------------------------------------------------------------------- 1 | package com.xlythe.textmanager.text.smil; 2 | 3 | import org.w3c.dom.DOMException; 4 | 5 | public interface DocumentEvent { 6 | /** 7 | * 8 | * @param eventType The eventType parameter specifies the 9 | * type of Event interface to be created. If the 10 | * Event interface specified is supported by the 11 | * implementation this method will return a new Event of 12 | * the interface type requested. If the Event is to be 13 | * dispatched via the dispatchEvent method the 14 | * appropriate event init method must be called after creation in 15 | * order to initialize the Event's values. As an example, 16 | * a user wishing to synthesize some kind of UIEvent 17 | * would call createEvent with the parameter "UIEvents". 18 | * The initUIEvent method could then be called on the 19 | * newly created UIEvent to set the specific type of 20 | * UIEvent to be dispatched and set its context information.The 21 | * createEvent method is used in creating 22 | * Events when it is either inconvenient or unnecessary 23 | * for the user to create an Event themselves. In cases 24 | * where the implementation provided Event is 25 | * insufficient, users may supply their own Event 26 | * implementations for use with the dispatchEvent method. 27 | * @return The newly created Event 28 | * @exception DOMException 29 | * NOT_SUPPORTED_ERR: Raised if the implementation does not support the 30 | * type of Event interface requested 31 | */ 32 | Event createEvent(String eventType) 33 | throws DOMException; 34 | 35 | } 36 | -------------------------------------------------------------------------------- /android-text-manager/src/main/java/com/xlythe/textmanager/text/smil/ElementLayout.java: -------------------------------------------------------------------------------- 1 | package com.xlythe.textmanager.text.smil; 2 | 3 | import org.w3c.dom.DOMException; 4 | 5 | public interface ElementLayout { 6 | /** 7 | * @exception DOMException 8 | * NO_MODIFICATION_ALLOWED_ERR: Raised if this attribute is readonly. 9 | */ 10 | String getTitle(); 11 | void setTitle(String title) 12 | throws DOMException; 13 | 14 | /** 15 | * @exception DOMException 16 | * NO_MODIFICATION_ALLOWED_ERR: Raised if this attribute is readonly. 17 | */ 18 | String getBackgroundColor(); 19 | void setBackgroundColor(String backgroundColor) 20 | throws DOMException; 21 | 22 | /** 23 | * @exception DOMException 24 | * NO_MODIFICATION_ALLOWED_ERR: Raised if this attribute is readonly. 25 | */ 26 | int getHeight(); 27 | void setHeight(int height) 28 | throws DOMException; 29 | 30 | /** 31 | * @exception DOMException 32 | * NO_MODIFICATION_ALLOWED_ERR: Raised if this attribute is readonly. 33 | */ 34 | int getWidth(); 35 | void setWidth(int width) 36 | throws DOMException; 37 | 38 | } -------------------------------------------------------------------------------- /android-text-manager/src/main/java/com/xlythe/textmanager/text/smil/ElementParallelTimeContainer.java: -------------------------------------------------------------------------------- 1 | package com.xlythe.textmanager.text.smil; 2 | 3 | import org.w3c.dom.DOMException; 4 | 5 | public interface ElementParallelTimeContainer extends ElementTimeContainer { 6 | /** 7 | * Controls the end of the container. Need to address thr id-ref value. 8 | * @exception DOMException 9 | * NO_MODIFICATION_ALLOWED_ERR: Raised if this attribute is readonly. 10 | */ 11 | String getEndSync(); 12 | void setEndSync(String endSync) 13 | throws DOMException; 14 | 15 | /** 16 | * This method returns the implicit duration in seconds. 17 | * @return The implicit duration in seconds or -1 if the implicit is 18 | * unknown (indefinite?). 19 | */ 20 | float getImplicitDuration(); 21 | 22 | } -------------------------------------------------------------------------------- /android-text-manager/src/main/java/com/xlythe/textmanager/text/smil/ElementSequentialTimeContainer.java: -------------------------------------------------------------------------------- 1 | package com.xlythe.textmanager.text.smil; 2 | 3 | public interface ElementSequentialTimeContainer extends ElementTimeContainer { 4 | } -------------------------------------------------------------------------------- /android-text-manager/src/main/java/com/xlythe/textmanager/text/smil/ElementSequentialTimeContainerImpl.java: -------------------------------------------------------------------------------- 1 | package com.xlythe.textmanager.text.smil; 2 | 3 | import org.w3c.dom.Node; 4 | import org.w3c.dom.NodeList; 5 | 6 | import java.util.ArrayList; 7 | 8 | public abstract class ElementSequentialTimeContainerImpl extends 9 | ElementTimeContainerImpl implements ElementSequentialTimeContainer { 10 | 11 | /* 12 | * Internal Interface 13 | */ 14 | 15 | ElementSequentialTimeContainerImpl(SMILElement element) { 16 | super(element); 17 | } 18 | 19 | /* 20 | * ElementSequentialTimeContainer Interface 21 | */ 22 | 23 | public NodeList getActiveChildrenAt(float instant) { 24 | NodeList allChildren = this.getTimeChildren(); 25 | ArrayList nodes = new ArrayList<>(); 26 | for (int i = 0; i < allChildren.getLength(); i++) { 27 | instant -= ((ElementTime) allChildren.item(i)).getDur(); 28 | if (instant < 0) { 29 | nodes.add(allChildren.item(i)); 30 | return new NodeListImpl(nodes); 31 | } 32 | } 33 | return new NodeListImpl(nodes); 34 | } 35 | 36 | public float getDur() { 37 | float dur = super.getDur(); 38 | if (dur == 0) { 39 | NodeList children = getTimeChildren(); 40 | for (int i = 0; i < children.getLength(); ++i) { 41 | ElementTime child = (ElementTime) children.item(i); 42 | if (child.getDur() < 0) { 43 | // Return "indefinite" since containing a child whose duration is indefinite. 44 | return -1.0F; 45 | } 46 | dur += child.getDur(); 47 | } 48 | } 49 | return dur; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /android-text-manager/src/main/java/com/xlythe/textmanager/text/smil/ElementTimeContainer.java: -------------------------------------------------------------------------------- 1 | package com.xlythe.textmanager.text.smil; 2 | 3 | import org.w3c.dom.NodeList; 4 | 5 | public interface ElementTimeContainer extends ElementTime { 6 | /** 7 | * A NodeList that contains all timed childrens of this node. If there are 8 | * no timed children, the Nodelist is empty. An iterator 9 | * is more appropriate here than a node list but it requires Traversal 10 | * module support. 11 | */ 12 | NodeList getTimeChildren(); 13 | 14 | /** 15 | * Returns a list of child elements active at the specified invocation. 16 | * @param instant The desired position on the local timeline in 17 | * milliseconds. 18 | * @return List of timed child-elements active at instant. 19 | */ 20 | NodeList getActiveChildrenAt(float instant); 21 | 22 | } -------------------------------------------------------------------------------- /android-text-manager/src/main/java/com/xlythe/textmanager/text/smil/ElementTimeContainerImpl.java: -------------------------------------------------------------------------------- 1 | package com.xlythe.textmanager.text.smil; 2 | 3 | public abstract class ElementTimeContainerImpl extends ElementTimeImpl implements 4 | ElementTimeContainer { 5 | 6 | /* 7 | * Internal Interface 8 | */ 9 | 10 | ElementTimeContainerImpl(SMILElement element) { 11 | super(element); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /android-text-manager/src/main/java/com/xlythe/textmanager/text/smil/EventException.java: -------------------------------------------------------------------------------- 1 | package com.xlythe.textmanager.text.smil; 2 | 3 | public class EventException extends RuntimeException { 4 | public EventException(short code, String message) { 5 | super(message); 6 | this.code = code; 7 | } 8 | public short code; 9 | // EventExceptionCode 10 | /** 11 | * If the Event's type was not specified by initializing the 12 | * event before the method was called. Specification of the Event's type 13 | * as null or an empty string will also trigger this 14 | * exception. 15 | */ 16 | public static final short UNSPECIFIED_EVENT_TYPE_ERR = 0; 17 | 18 | } 19 | -------------------------------------------------------------------------------- /android-text-manager/src/main/java/com/xlythe/textmanager/text/smil/EventListener.java: -------------------------------------------------------------------------------- 1 | package com.xlythe.textmanager.text.smil; 2 | 3 | public interface EventListener { 4 | /** 5 | * This method is called whenever an event occurs of the type for which 6 | * the EventListener interface was registered. 7 | * @param evt The Event contains contextual information 8 | * about the event. It also contains the stopPropagation 9 | * and preventDefault methods which are used in 10 | * determining the event's flow and default action. 11 | */ 12 | void handleEvent(Event evt); 13 | 14 | } -------------------------------------------------------------------------------- /android-text-manager/src/main/java/com/xlythe/textmanager/text/smil/LayoutParameters.java: -------------------------------------------------------------------------------- 1 | package com.xlythe.textmanager.text.smil; 2 | 3 | public interface LayoutParameters { 4 | /* Layouts type definition */ 5 | int UNKNOWN = -1; 6 | int HVGA_LANDSCAPE = 10; 7 | int HVGA_PORTRAIT = 11; 8 | 9 | /* Parameters for known layouts */ 10 | int HVGA_LANDSCAPE_WIDTH = 480; 11 | int HVGA_LANDSCAPE_HEIGHT = 320; 12 | int HVGA_PORTRAIT_WIDTH = 320; 13 | int HVGA_PORTRAIT_HEIGHT = 480; 14 | 15 | /** 16 | * Get the width of current layout. 17 | */ 18 | int getWidth(); 19 | /** 20 | * Get the height of current layout. 21 | */ 22 | int getHeight(); 23 | /** 24 | * Get the width of the image region of current layout. 25 | */ 26 | int getImageHeight(); 27 | /** 28 | * Get the height of the text region of current layout. 29 | */ 30 | int getTextHeight(); 31 | /** 32 | * Get the type of current layout. 33 | */ 34 | int getType(); 35 | /** 36 | * Get the type description of current layout. 37 | */ 38 | String getTypeDescription(); 39 | } -------------------------------------------------------------------------------- /android-text-manager/src/main/java/com/xlythe/textmanager/text/smil/NamedNodeMapImpl.java: -------------------------------------------------------------------------------- 1 | package com.xlythe.textmanager.text.smil; 2 | 3 | import org.w3c.dom.DOMException; 4 | import org.w3c.dom.NamedNodeMap; 5 | import org.w3c.dom.Node; 6 | 7 | import java.util.Vector; 8 | 9 | public class NamedNodeMapImpl implements NamedNodeMap { 10 | 11 | private Vector mNodes = new Vector<>(); 12 | 13 | public int getLength() { 14 | return mNodes.size(); 15 | } 16 | 17 | public Node getNamedItem(String name) { 18 | Node node = null; 19 | for (int i = 0; i < mNodes.size(); i++) { 20 | if (name.equals(mNodes.elementAt(i).getNodeName())) { 21 | node = mNodes.elementAt(i); 22 | break; 23 | } 24 | } 25 | return node; 26 | } 27 | 28 | public Node getNamedItemNS(String namespaceURI, String localName) { 29 | // TODO Auto-generated method stub 30 | return null; 31 | } 32 | 33 | public Node item(int index) { 34 | if (index < mNodes.size()) { 35 | return mNodes.elementAt(index); 36 | } 37 | return null; 38 | } 39 | 40 | public Node removeNamedItem(String name) throws DOMException { 41 | Node node = getNamedItem(name); 42 | if (node == null) { 43 | throw new DOMException(DOMException.NOT_FOUND_ERR, "Not found"); 44 | } else { 45 | mNodes.remove(node); 46 | } 47 | return node; 48 | } 49 | 50 | public Node removeNamedItemNS(String namespaceURI, String localName) 51 | throws DOMException { 52 | // TODO Auto-generated method stub 53 | return null; 54 | } 55 | 56 | public Node setNamedItem(Node arg) throws DOMException { 57 | Node existing = getNamedItem(arg.getNodeName()); 58 | if (existing != null) { 59 | mNodes.remove(existing); 60 | } 61 | mNodes.add(arg); 62 | return existing; 63 | } 64 | 65 | public Node setNamedItemNS(Node arg) throws DOMException { 66 | // TODO Auto-generated method stub 67 | return null; 68 | } 69 | 70 | } -------------------------------------------------------------------------------- /android-text-manager/src/main/java/com/xlythe/textmanager/text/smil/SMILDocument.java: -------------------------------------------------------------------------------- 1 | package com.xlythe.textmanager.text.smil; 2 | 3 | import org.w3c.dom.Document; 4 | 5 | public interface SMILDocument extends Document, ElementSequentialTimeContainer { 6 | 7 | /** 8 | * Returns the element that contains the layout node of this document, 9 | * i.e. the HEAD element. 10 | */ 11 | SMILElement getHead(); 12 | 13 | /** 14 | * Returns the element that contains the par's of the document, i.e. the 15 | * BODY element. 16 | */ 17 | SMILElement getBody(); 18 | 19 | /** 20 | * Returns the element that contains the layout information of the presentation, 21 | * i.e. the LAYOUT element. 22 | */ 23 | SMILLayoutElement getLayout(); 24 | } -------------------------------------------------------------------------------- /android-text-manager/src/main/java/com/xlythe/textmanager/text/smil/SMILElement.java: -------------------------------------------------------------------------------- 1 | package com.xlythe.textmanager.text.smil; 2 | 3 | import org.w3c.dom.DOMException; 4 | import org.w3c.dom.Element; 5 | 6 | public interface SMILElement extends Element { 7 | /** 8 | * The unique id. 9 | * @exception DOMException 10 | * NO_MODIFICATION_ALLOWED_ERR: Raised if this attribute is readonly. 11 | */ 12 | String getId(); 13 | void setId(String id) 14 | throws DOMException; 15 | 16 | } -------------------------------------------------------------------------------- /android-text-manager/src/main/java/com/xlythe/textmanager/text/smil/SMILLayoutElement.java: -------------------------------------------------------------------------------- 1 | package com.xlythe.textmanager.text.smil; 2 | 3 | import org.w3c.dom.NodeList; 4 | 5 | public interface SMILLayoutElement extends SMILElement { 6 | /** 7 | * The mime type of the layout langage used in this layout element.The 8 | * default value of the type attribute is "text/smil-basic-layout". 9 | */ 10 | public String getType(); 11 | 12 | /** 13 | * true if the player can understand the mime type, 14 | * false otherwise. 15 | */ 16 | public boolean getResolved(); 17 | 18 | /** 19 | * Returns the root layout element of this document. 20 | */ 21 | public SMILRootLayoutElement getRootLayout(); 22 | 23 | /** 24 | * Return the region elements of this document. 25 | */ 26 | public NodeList getRegions(); 27 | } 28 | -------------------------------------------------------------------------------- /android-text-manager/src/main/java/com/xlythe/textmanager/text/smil/SMILParElement.java: -------------------------------------------------------------------------------- 1 | package com.xlythe.textmanager.text.smil; 2 | 3 | public interface SMILParElement extends ElementParallelTimeContainer, SMILElement { 4 | 5 | } -------------------------------------------------------------------------------- /android-text-manager/src/main/java/com/xlythe/textmanager/text/smil/SMILRefElement.java: -------------------------------------------------------------------------------- 1 | package com.xlythe.textmanager.text.smil; 2 | 3 | public interface SMILRefElement extends SMILMediaElement { 4 | } 5 | -------------------------------------------------------------------------------- /android-text-manager/src/main/java/com/xlythe/textmanager/text/smil/SMILRegionElement.java: -------------------------------------------------------------------------------- 1 | package com.xlythe.textmanager.text.smil; 2 | 3 | import org.w3c.dom.DOMException; 4 | 5 | public interface SMILRegionElement extends SMILElement, ElementLayout { 6 | /** 7 | * @exception DOMException 8 | * NO_MODIFICATION_ALLOWED_ERR: Raised if this attribute is readonly. 9 | */ 10 | String getFit(); 11 | void setFit(String fit) 12 | throws DOMException; 13 | 14 | /** 15 | * @exception DOMException 16 | * NO_MODIFICATION_ALLOWED_ERR: Raised if this attribute is readonly. 17 | */ 18 | int getLeft(); 19 | void setLeft(int top) 20 | throws DOMException; 21 | 22 | /** 23 | * @exception DOMException 24 | * NO_MODIFICATION_ALLOWED_ERR: Raised if this attribute is readonly. 25 | */ 26 | int getTop(); 27 | void setTop(int top) 28 | throws DOMException; 29 | 30 | /** 31 | * @exception DOMException 32 | * NO_MODIFICATION_ALLOWED_ERR: Raised if this attribute is readonly. 33 | */ 34 | int getZIndex(); 35 | void setZIndex(int zIndex) 36 | throws DOMException; 37 | 38 | } -------------------------------------------------------------------------------- /android-text-manager/src/main/java/com/xlythe/textmanager/text/smil/SMILRegionInterface.java: -------------------------------------------------------------------------------- 1 | package com.xlythe.textmanager.text.smil; 2 | 3 | public interface SMILRegionInterface { 4 | SMILRegionElement getRegion(); 5 | void setRegion(SMILRegionElement region); 6 | } -------------------------------------------------------------------------------- /android-text-manager/src/main/java/com/xlythe/textmanager/text/smil/SMILRegionMediaElement.java: -------------------------------------------------------------------------------- 1 | package com.xlythe.textmanager.text.smil; 2 | 3 | public interface SMILRegionMediaElement extends SMILMediaElement, 4 | SMILRegionInterface { 5 | } 6 | -------------------------------------------------------------------------------- /android-text-manager/src/main/java/com/xlythe/textmanager/text/smil/SMILRootLayoutElement.java: -------------------------------------------------------------------------------- 1 | package com.xlythe.textmanager.text.smil; 2 | 3 | public interface SMILRootLayoutElement extends SMILElement, ElementLayout { 4 | } -------------------------------------------------------------------------------- /android-text-manager/src/main/java/com/xlythe/textmanager/text/smil/SmilElementImpl.java: -------------------------------------------------------------------------------- 1 | package com.xlythe.textmanager.text.smil; 2 | 3 | import org.w3c.dom.DOMException; 4 | 5 | public class SmilElementImpl extends ElementImpl implements SMILElement { 6 | /** 7 | * This constructor is used by the factory methods of the SmilDocument. 8 | * 9 | * @param owner The SMIL document to which this element belongs to 10 | * @param tagName The tag name of the element 11 | */ 12 | SmilElementImpl(SmilDocumentImpl owner, String tagName) 13 | { 14 | super(owner, tagName.toLowerCase()); 15 | } 16 | 17 | public String getId() { 18 | // TODO Auto-generated method stub 19 | return null; 20 | } 21 | 22 | public void setId(String id) throws DOMException { 23 | // TODO Auto-generated method stub 24 | 25 | } 26 | 27 | } -------------------------------------------------------------------------------- /android-text-manager/src/main/java/com/xlythe/textmanager/text/smil/SmilLayoutElementImpl.java: -------------------------------------------------------------------------------- 1 | package com.xlythe.textmanager.text.smil; 2 | 3 | import org.w3c.dom.NodeList; 4 | 5 | public class SmilLayoutElementImpl extends SmilElementImpl implements 6 | SMILLayoutElement { 7 | SmilLayoutElementImpl(SmilDocumentImpl owner, String tagName) { 8 | super(owner, tagName); 9 | } 10 | 11 | public boolean getResolved() { 12 | // TODO Auto-generated method stub 13 | return false; 14 | } 15 | 16 | public String getType() { 17 | return this.getAttribute("type"); 18 | } 19 | 20 | public NodeList getRegions() { 21 | return this.getElementsByTagName("region"); 22 | } 23 | 24 | public SMILRootLayoutElement getRootLayout() { 25 | NodeList childNodes = this.getChildNodes(); 26 | SMILRootLayoutElement rootLayoutNode = null; 27 | int childrenCount = childNodes.getLength(); 28 | for (int i = 0; i < childrenCount; i++) { 29 | if (childNodes.item(i).getNodeName().equals("root-layout")) { 30 | rootLayoutNode = (SMILRootLayoutElement)childNodes.item(i); 31 | } 32 | } 33 | if (null == rootLayoutNode) { 34 | // root-layout node is not set. Create a default one. 35 | rootLayoutNode = (SMILRootLayoutElement) getOwnerDocument().createElement("root-layout"); 36 | rootLayoutNode.setWidth(LayoutManager.getInstance().getLayoutParameters().getWidth()); 37 | rootLayoutNode.setHeight(LayoutManager.getInstance().getLayoutParameters().getHeight()); 38 | appendChild(rootLayoutNode); 39 | } 40 | return rootLayoutNode; 41 | } 42 | 43 | } -------------------------------------------------------------------------------- /android-text-manager/src/main/java/com/xlythe/textmanager/text/smil/SmilRefElementImpl.java: -------------------------------------------------------------------------------- 1 | package com.xlythe.textmanager.text.smil; 2 | 3 | public class SmilRefElementImpl extends SmilRegionMediaElementImpl implements 4 | SMILRefElement { 5 | 6 | SmilRefElementImpl(SmilDocumentImpl owner, String tagName) { 7 | super(owner, tagName); 8 | } 9 | 10 | } -------------------------------------------------------------------------------- /android-text-manager/src/main/java/com/xlythe/textmanager/text/smil/SmilRegionMediaElementImpl.java: -------------------------------------------------------------------------------- 1 | package com.xlythe.textmanager.text.smil; 2 | 3 | import org.w3c.dom.NodeList; 4 | 5 | public class SmilRegionMediaElementImpl extends SmilMediaElementImpl implements 6 | SMILRegionMediaElement { 7 | private SMILRegionElement mRegion; 8 | 9 | SmilRegionMediaElementImpl(SmilDocumentImpl owner, String tagName) { 10 | super(owner, tagName); 11 | } 12 | 13 | public SMILRegionElement getRegion() { 14 | if (mRegion == null) { 15 | SMILDocument doc = (SMILDocument)this.getOwnerDocument(); 16 | NodeList regions = doc.getLayout().getElementsByTagName("region"); 17 | SMILRegionElement region; 18 | for (int i = 0; i < regions.getLength(); i++) { 19 | region = (SMILRegionElement)regions.item(i); 20 | if (region.getId().equals(this.getAttribute("region"))) { 21 | mRegion = region; 22 | } 23 | } 24 | } 25 | return mRegion; 26 | } 27 | 28 | public void setRegion(SMILRegionElement region) { 29 | this.setAttribute("region", region.getId()); 30 | mRegion = region; 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /android-text-manager/src/main/java/com/xlythe/textmanager/text/smil/TimeList.java: -------------------------------------------------------------------------------- 1 | package com.xlythe.textmanager.text.smil; 2 | 3 | public interface TimeList { 4 | /** 5 | * Returns the index th item in the collection. If 6 | * index is greater than or equal to the number of times in 7 | * the list, this returns null . 8 | * @param index Index into the collection. 9 | * @return The time at the index th position in the 10 | * TimeList , or null if that is not a valid 11 | * index. 12 | */ 13 | Time item(int index); 14 | 15 | /** 16 | * The number of times in the list. The range of valid child time indices 17 | * is 0 to length-1 inclusive. 18 | */ 19 | int getLength(); 20 | 21 | } -------------------------------------------------------------------------------- /android-text-manager/src/main/java/com/xlythe/textmanager/text/smil/TimeListImpl.java: -------------------------------------------------------------------------------- 1 | package com.xlythe.textmanager.text.smil; 2 | 3 | import java.util.ArrayList; 4 | 5 | public class TimeListImpl implements TimeList { 6 | private final ArrayList