Revert "Remove abandoned implementation." am: 8a3204f485 am: 47b44bbd3e
Original change: https://android-review.googlesource.com/c/platform/packages/apps/Messaging/+/3255819 Change-Id: I92d6c8d6895b4b51d2745558003cbf3b11b03f14 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
104
Android.bp
Normal file
@@ -0,0 +1,104 @@
|
||||
// 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",
|
||||
],
|
||||
}
|
||||
|
||||
soong_config_module_type {
|
||||
name: "messaging_java_defaults",
|
||||
module_type: "java_defaults",
|
||||
config_namespace: "messaging",
|
||||
bool_variables: ["build_variant_eng"],
|
||||
properties: ["optimize"],
|
||||
}
|
||||
|
||||
messaging_java_defaults {
|
||||
name: "messaging_defaults",
|
||||
soong_config_variables: {
|
||||
build_variant_eng: {
|
||||
optimize: {
|
||||
proguard_flags_files: [
|
||||
"proguard.flags",
|
||||
"proguard-test.flags",
|
||||
],
|
||||
},
|
||||
conditions_default: {
|
||||
optimize: {
|
||||
proguard_flags_files: [
|
||||
"proguard.flags",
|
||||
"proguard-release.flags",
|
||||
],
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
android_app {
|
||||
name: "messaging",
|
||||
|
||||
srcs: ["src/**/*.java"],
|
||||
|
||||
defaults: ["messaging_defaults"],
|
||||
|
||||
static_libs: [
|
||||
"androidx.appcompat_appcompat",
|
||||
"androidx.collection_collection",
|
||||
"androidx.core_core",
|
||||
"androidx.fragment_fragment",
|
||||
"androidx.media_media",
|
||||
"androidx.legacy_legacy-support-core-utils",
|
||||
"androidx.legacy_legacy-support-core-ui",
|
||||
"androidx.palette_palette",
|
||||
"androidx.recyclerview_recyclerview",
|
||||
"androidx.viewpager_viewpager",
|
||||
"androidx.legacy_legacy-support-v13",
|
||||
"colorpicker",
|
||||
"libchips",
|
||||
"libphotoviewer",
|
||||
"androidx.annotation_annotation",
|
||||
"android-common",
|
||||
"android-common-framesequence",
|
||||
"com.android.vcard",
|
||||
"guava",
|
||||
"libphonenumber",
|
||||
],
|
||||
|
||||
aaptflags: [
|
||||
"--version-name",
|
||||
"1.0.001",
|
||||
"--version-code",
|
||||
"10001040",
|
||||
],
|
||||
required: [
|
||||
"libframesequence",
|
||||
"libgiftranscode",
|
||||
],
|
||||
optimize: {
|
||||
obfuscate: true,
|
||||
optimize: true,
|
||||
enabled: true,
|
||||
},
|
||||
|
||||
certificate: "platform",
|
||||
|
||||
sdk_version: "current",
|
||||
|
||||
product_specific: true,
|
||||
}
|
||||
533
AndroidManifest.xml
Normal file
@@ -0,0 +1,533 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.android.messaging"
|
||||
android:installLocation="internalOnly">
|
||||
|
||||
<uses-sdk android:minSdkVersion="19" android:targetSdkVersion="24" />
|
||||
|
||||
<!-- Application holds CPU wakelock while working in background -->
|
||||
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
||||
<!-- Application needs SMS/MMS permissions -->
|
||||
<uses-permission android:name="android.permission.READ_SMS"/>
|
||||
<uses-permission android:name="android.permission.WRITE_SMS"/>
|
||||
<uses-permission android:name="android.permission.RECEIVE_SMS"/>
|
||||
<uses-permission android:name="android.permission.RECEIVE_MMS"/>
|
||||
<uses-permission android:name="android.permission.SEND_SMS"/>
|
||||
<!-- Application needs access to MMS network -->
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
|
||||
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
|
||||
<!-- Application needs CONTACT permissions -->
|
||||
<uses-permission android:name="android.permission.READ_CONTACTS"/>
|
||||
<uses-permission android:name="android.permission.WRITE_CONTACTS"/>
|
||||
<!-- Application needs to read profiles for the user itself from CP2 -->
|
||||
<uses-permission android:name="android.permission.READ_PROFILE"/>
|
||||
<uses-permission android:name="android.permission.VIBRATE"/>
|
||||
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
|
||||
|
||||
<uses-permission android:name="android.permission.CAMERA" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
|
||||
<uses-permission android:name="android.permission.RECORD_AUDIO" />
|
||||
<uses-permission android:name="android.permission.CALL_PHONE" />
|
||||
<uses-permission android:name="android.permission.DOWNLOAD_WITHOUT_NOTIFICATION" />
|
||||
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
|
||||
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
|
||||
|
||||
<!-- Optional features -->
|
||||
<uses-feature android:name="android.hardware.camera" android:required="false" />
|
||||
<uses-feature android:name="android.hardware.camera.front" android:required="false" />
|
||||
<uses-feature android:name="android.hardware.camera.autofocus" android:required="false" />
|
||||
<uses-feature android:name="android.hardware.microphone" android:required="false" />
|
||||
<uses-feature android:name="android.hardware.screen.portrait" android:required="false" />
|
||||
|
||||
<application
|
||||
android:name="com.android.messaging.BugleApplication"
|
||||
android:allowBackup="false"
|
||||
android:icon="@drawable/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:theme="@style/BugleTheme"
|
||||
android:supportsRtl="true">
|
||||
|
||||
<!-- Displays a list of conversations -->
|
||||
<activity
|
||||
android:name=".ui.conversationlist.ConversationListActivity"
|
||||
android:configChanges="orientation|screenSize|keyboardHidden"
|
||||
android:screenOrientation="user"
|
||||
android:label="@string/app_name"
|
||||
android:exported="true"
|
||||
android:theme="@style/BugleTheme.ConversationListActivity">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.APP_MESSAGING" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".ui.PermissionCheckActivity"
|
||||
android:screenOrientation="portrait"
|
||||
android:configChanges="orientation|screenSize|keyboardHidden" />
|
||||
|
||||
<!-- Launches a conversation (ensures correct app name shown in recents) -->
|
||||
<activity
|
||||
android:name=".ui.conversation.LaunchConversationActivity"
|
||||
android:configChanges="orientation|screenSize|keyboardHidden"
|
||||
android:screenOrientation="user"
|
||||
android:theme="@style/Invisible"
|
||||
android:noHistory="true"
|
||||
android:exported="true"
|
||||
android:documentLaunchMode="always">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<action android:name="android.intent.action.SENDTO" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
<data android:scheme="sms" />
|
||||
<data android:scheme="smsto" />
|
||||
<data android:scheme="mms" />
|
||||
<data android:scheme="mmsto" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<!-- Displays a list of archived conversations -->
|
||||
<activity
|
||||
android:name=".ui.conversationlist.ArchivedConversationListActivity"
|
||||
android:configChanges="orientation|screenSize|keyboardHidden"
|
||||
android:screenOrientation="user"
|
||||
android:label="@string/archived_activity_title"
|
||||
android:theme="@style/BugleTheme.ArchivedConversationListActivity"
|
||||
android:parentActivityName="com.android.messaging.ui.conversationlist.ConversationListActivity">
|
||||
<meta-data
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value="com.android.messaging.ui.conversationlist.ConversationListActivity" />
|
||||
</activity>
|
||||
|
||||
<!-- Displays the contents of a single conversation -->
|
||||
<activity
|
||||
android:name=".ui.conversation.ConversationActivity"
|
||||
android:configChanges="orientation|screenSize|keyboardHidden"
|
||||
android:screenOrientation="user"
|
||||
android:windowSoftInputMode="stateHidden|adjustResize"
|
||||
android:theme="@style/BugleTheme.ConversationActivity"
|
||||
android:parentActivityName="com.android.messaging.ui.conversationlist.ConversationListActivity">
|
||||
<meta-data
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value="com.android.messaging.ui.conversationlist.ConversationListActivity" />
|
||||
</activity>
|
||||
|
||||
<!-- Blocked Participants -->
|
||||
<activity
|
||||
android:name=".ui.BlockedParticipantsActivity"
|
||||
android:configChanges="orientation|screenSize|keyboardHidden"
|
||||
android:screenOrientation="user"
|
||||
android:label="@string/blocked_contacts_title"
|
||||
android:theme="@style/BugleTheme"
|
||||
android:parentActivityName="com.android.messaging.ui.conversationlist.ConversationListActivity">
|
||||
<meta-data
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value="com.android.messaging.ui.conversationlist.ConversationListActivity" />
|
||||
</activity>
|
||||
|
||||
<!-- Full-screen photo viewer -->
|
||||
<activity
|
||||
android:name=".ui.photoviewer.BuglePhotoViewActivity"
|
||||
android:label="@string/photo_view_activity_title"
|
||||
android:configChanges="orientation|screenSize|keyboardHidden"
|
||||
android:screenOrientation="user"
|
||||
android:theme="@style/BuglePhotoViewTheme"
|
||||
/>
|
||||
|
||||
<!-- Settings -->
|
||||
<activity
|
||||
android:name=".ui.appsettings.SettingsActivity"
|
||||
android:label="@string/settings_activity_title"
|
||||
android:theme="@style/BugleTheme.SettingsActivity"
|
||||
android:configChanges="orientation|screenSize|keyboardHidden"
|
||||
android:screenOrientation="user"
|
||||
android:parentActivityName="com.android.messaging.ui.conversationlist.ConversationListActivity">
|
||||
<meta-data
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value="com.android.messaging.ui.conversationlist.ConversationListActivity" />
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".ui.appsettings.PerSubscriptionSettingsActivity"
|
||||
android:label="@string/advanced_settings_activity_title"
|
||||
android:theme="@style/BugleTheme.SettingsActivity"
|
||||
android:configChanges="orientation|screenSize|keyboardHidden"
|
||||
android:screenOrientation="user"
|
||||
android:parentActivityName="com.android.messaging.ui.appsettings.SettingsActivity">
|
||||
<meta-data
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value="com.android.messaging.ui.appsettings.SettingsActivity" />
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".ui.appsettings.ApplicationSettingsActivity"
|
||||
android:label="@string/general_settings_activity_title"
|
||||
android:theme="@style/BugleTheme.SettingsActivity"
|
||||
android:configChanges="orientation|screenSize|keyboardHidden"
|
||||
android:screenOrientation="user"
|
||||
android:parentActivityName="com.android.messaging.ui.appsettings.SettingsActivity">
|
||||
<meta-data
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:exported="true"
|
||||
android:value="com.android.messaging.ui.appsettings.SettingsActivity" />
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.NOTIFICATION_PREFERENCES" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<!-- Handles sharing intent -->
|
||||
<activity
|
||||
android:name=".ui.conversationlist.ShareIntentActivity"
|
||||
android:configChanges="orientation|screenSize|keyboardHidden"
|
||||
android:screenOrientation="user"
|
||||
android:theme="@style/BugleTheme.DialogActivity"
|
||||
android:excludeFromRecents="true"
|
||||
android:exported="true"
|
||||
android:documentLaunchMode="always">
|
||||
<intent-filter
|
||||
android:label="@string/share_intent_label">
|
||||
<action android:name="android.intent.action.SEND" />
|
||||
<action android:name="android.intent.action.SEND_MULTIPLE" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<data android:mimeType="text/plain" />
|
||||
<data android:mimeType="text/x-vCard" />
|
||||
<data android:mimeType="text/x-vcard" />
|
||||
<data android:mimeType="image/*" />
|
||||
<data android:mimeType="audio/*" />
|
||||
<data android:mimeType="video/*" />
|
||||
<data android:mimeType="application/ogg" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<!-- People & Options -->
|
||||
<activity
|
||||
android:name=".ui.conversationsettings.PeopleAndOptionsActivity"
|
||||
android:configChanges="orientation|screenSize|keyboardHidden"
|
||||
android:screenOrientation="user"
|
||||
android:label="@string/people_and_options_activity_title"
|
||||
android:theme="@style/BugleTheme"
|
||||
android:parentActivityName="com.android.messaging.ui.conversation.ConversationActivity">
|
||||
<meta-data
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value="com.android.messaging.ui.conversation.ConversationActivity" />
|
||||
</activity>
|
||||
|
||||
<!-- License -->
|
||||
<activity android:name=".ui.LicenseActivity"
|
||||
android:exported="true"
|
||||
android:theme="@android:style/Theme.Holo.Light.Dialog"
|
||||
android:label="@string/menu_license">
|
||||
</activity>
|
||||
|
||||
<!-- Message Forwarding -->
|
||||
<activity
|
||||
android:name=".ui.conversationlist.ForwardMessageActivity"
|
||||
android:configChanges="orientation|screenSize|keyboardHidden"
|
||||
android:screenOrientation="user"
|
||||
android:label="@string/forward_message_activity_title"
|
||||
android:theme="@style/BugleTheme.DialogActivity">
|
||||
</activity>
|
||||
|
||||
<!-- Entry point for handling remote input/actions. Currently, this is only used by Android
|
||||
Wear to send voice replies. Since that uses PendingIntents, we don't need to export
|
||||
this activity. If we want other apps to be able to use this activity at will,
|
||||
we'll need to guard it with a signature-matching protected permission. We would also
|
||||
need to add an intent filter and remove the android:exported attribute. -->
|
||||
<activity
|
||||
android:name=".ui.RemoteInputEntrypointActivity"
|
||||
android:configChanges="orientation|screenSize|keyboardHidden"
|
||||
android:screenOrientation="user"
|
||||
android:exported="false"
|
||||
android:theme="@style/Invisible">
|
||||
</activity>
|
||||
|
||||
<!-- VCard details -->
|
||||
<activity
|
||||
android:name=".ui.VCardDetailActivity"
|
||||
android:configChanges="orientation|screenSize|keyboardHidden"
|
||||
android:screenOrientation="user"
|
||||
android:label="@string/vcard_detail_activity_title"
|
||||
android:theme="@style/BugleTheme">
|
||||
<meta-data
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value=".ui.conversation.ConversationActivity" />
|
||||
</activity>
|
||||
|
||||
<!-- Attachment chooser -->
|
||||
<activity
|
||||
android:name=".ui.attachmentchooser.AttachmentChooserActivity"
|
||||
android:configChanges="orientation|screenSize|keyboardHidden"
|
||||
android:screenOrientation="user"
|
||||
android:label="@string/attachment_chooser_activity_title"
|
||||
android:theme="@style/BugleTheme"
|
||||
android:parentActivityName="com.android.messaging.ui.conversation.ConversationActivity">
|
||||
<meta-data
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value="com.android.messaging.ui.conversation.ConversationActivity" />
|
||||
</activity>
|
||||
|
||||
<!-- Test activity that we use to host fragments/views. Unfortunately, apparently necessary
|
||||
because Android framework test cases want activity to be in the instrumented package.
|
||||
See http://developer.android.com/reference/android/test/ActivityInstrumentationTestCase2.html
|
||||
-->
|
||||
<activity
|
||||
android:name=".ui.TestActivity"
|
||||
android:configChanges="orientation|screenSize|keyboardHidden">
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".ui.debug.DebugMmsConfigActivity"
|
||||
android:configChanges="orientation|screenSize|keyboardHidden"
|
||||
android:screenOrientation="user"
|
||||
android:theme="@style/BugleTheme.DialogActivity"
|
||||
android:exported="false">
|
||||
</activity>
|
||||
|
||||
<provider android:name=".datamodel.MessagingContentProvider" android:label="@string/app_name"
|
||||
android:authorities="com.android.messaging.datamodel.MessagingContentProvider"
|
||||
android:exported="false" >
|
||||
</provider>
|
||||
|
||||
<provider android:name=".datamodel.MmsFileProvider"
|
||||
android:authorities="com.android.messaging.datamodel.MmsFileProvider"
|
||||
android:grantUriPermissions="true"
|
||||
android:exported="false" />
|
||||
|
||||
<provider android:name=".datamodel.MediaScratchFileProvider"
|
||||
android:authorities="com.android.messaging.datamodel.MediaScratchFileProvider"
|
||||
android:grantUriPermissions="true"
|
||||
android:exported="false" />
|
||||
|
||||
|
||||
<!-- Action Services -->
|
||||
<service android:name=".datamodel.action.ActionServiceImpl"
|
||||
android:permission="android.permission.BIND_JOB_SERVICE"
|
||||
android:exported="true"/>
|
||||
<service android:name=".datamodel.action.BackgroundWorkerService"
|
||||
android:permission="android.permission.BIND_JOB_SERVICE"
|
||||
android:exported="true"/>
|
||||
|
||||
<!-- Sms and Mms related items -->
|
||||
|
||||
<!-- Intents for Notification and Pre-KLP Delivery -->
|
||||
<!-- Registered with the highest possible priority (max_int) -->
|
||||
<receiver android:name=".receiver.MmsWapPushReceiver"
|
||||
android:enabled="false"
|
||||
android:exported="true"
|
||||
android:permission="android.permission.BROADCAST_WAP_PUSH">
|
||||
<intent-filter android:priority="2147483647">
|
||||
<action android:name="android.provider.Telephony.WAP_PUSH_RECEIVED" />
|
||||
<data android:mimeType="application/vnd.wap.mms-message" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
<receiver android:name=".receiver.SmsReceiver"
|
||||
android:enabled="false"
|
||||
android:exported="true"
|
||||
android:permission="android.permission.BROADCAST_SMS">
|
||||
<intent-filter android:priority="2147483647">
|
||||
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
|
||||
</intent-filter>
|
||||
<intent-filter android:priority="2147483647">
|
||||
<action android:name="android.provider.Telephony.MMS_DOWNLOADED" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
<!-- Intents for aborting SMS/MMS broadcasts pre-KLP -->
|
||||
<!-- Registered for a priority just ahead of inbox Messaging apps (2) -->
|
||||
<receiver android:name=".receiver.AbortMmsWapPushReceiver"
|
||||
android:enabled="false"
|
||||
android:exported="true"
|
||||
android:permission="android.permission.BROADCAST_WAP_PUSH">
|
||||
<intent-filter android:priority="3">
|
||||
<action android:name="android.provider.Telephony.WAP_PUSH_RECEIVED" />
|
||||
<data android:mimeType="application/vnd.wap.mms-message" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
<receiver android:name=".receiver.AbortSmsReceiver"
|
||||
android:enabled="false"
|
||||
android:exported="true"
|
||||
android:permission="android.permission.BROADCAST_SMS">
|
||||
<intent-filter android:priority="3">
|
||||
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
<!-- Intents for KLP+ Delivery -->
|
||||
<receiver android:name=".receiver.MmsWapPushDeliverReceiver"
|
||||
android:exported="true"
|
||||
android:permission="android.permission.BROADCAST_WAP_PUSH">
|
||||
<intent-filter>
|
||||
<action android:name="android.provider.Telephony.WAP_PUSH_DELIVER" />
|
||||
<data android:mimeType="application/vnd.wap.mms-message" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
<receiver android:name=".receiver.SmsDeliverReceiver"
|
||||
android:exported="true"
|
||||
android:permission="android.permission.BROADCAST_SMS">
|
||||
<intent-filter>
|
||||
<action android:name="android.provider.Telephony.SMS_DELIVER" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
<receiver android:name=".receiver.SendStatusReceiver"
|
||||
android:exported="false">
|
||||
<intent-filter>
|
||||
<action android:name="com.android.messaging.receiver.SendStatusReceiver.MESSAGE_SENT" />
|
||||
<data android:scheme="content" />
|
||||
</intent-filter>
|
||||
<intent-filter>
|
||||
<action android:name="com.android.messaging.receiver.SendStatusReceiver.MESSAGE_DELIVERED" />
|
||||
</intent-filter>
|
||||
<intent-filter>
|
||||
<action android:name="com.android.messaging.receiver.SendStatusReceiver.MMS_SENT" />
|
||||
<data android:scheme="content" />
|
||||
</intent-filter>
|
||||
<intent-filter>
|
||||
<action android:name="com.android.messaging.receiver.SendStatusReceiver.MMS_DOWNLOADED" />
|
||||
<data android:scheme="content" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
<service android:name=".datamodel.NoConfirmationSmsSendService"
|
||||
android:permission="android.permission.SEND_RESPOND_VIA_MESSAGE"
|
||||
android:exported="true" >
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.RESPOND_VIA_MESSAGE" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<data android:scheme="sms" />
|
||||
<data android:scheme="smsto" />
|
||||
<data android:scheme="mms" />
|
||||
<data android:scheme="mmsto" />
|
||||
</intent-filter>
|
||||
</service>
|
||||
|
||||
<activity android:name=".ui.ClassZeroActivity"
|
||||
android:configChanges="orientation|screenSize|keyboardHidden"
|
||||
android:screenOrientation="user"
|
||||
android:label="@string/class_0_message_activity"
|
||||
android:theme="@style/BugleTheme.DialogActivity"
|
||||
android:launchMode="singleTask"
|
||||
android:excludeFromRecents="true">
|
||||
</activity>
|
||||
|
||||
<activity android:name=".ui.SmsStorageLowWarningActivity"
|
||||
android:theme="@style/Translucent"
|
||||
android:configChanges="orientation|screenSize|keyboardHidden" />
|
||||
|
||||
<activity android:name=".ui.appsettings.ApnSettingsActivity"
|
||||
android:configChanges="orientation|screenSize|keyboardHidden"
|
||||
android:screenOrientation="user"
|
||||
android:theme="@style/BugleTheme"
|
||||
android:parentActivityName="com.android.messaging.ui.appsettings.SettingsActivity" />
|
||||
|
||||
<activity android:name=".ui.appsettings.ApnEditorActivity"
|
||||
android:configChanges="orientation|screenSize|keyboardHidden"
|
||||
android:screenOrientation="user"
|
||||
android:theme="@style/BugleTheme"
|
||||
android:parentActivityName="com.android.messaging.ui.appsettings.ApnSettingsActivity"/>
|
||||
|
||||
<receiver android:name=".receiver.StorageStatusReceiver"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.DEVICE_STORAGE_LOW" />
|
||||
</intent-filter>
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.DEVICE_STORAGE_OK" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
<receiver android:name=".receiver.BootAndPackageReplacedReceiver"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.BOOT_COMPLETED"/>
|
||||
<action android:name="android.intent.action.MY_PACKAGE_REPLACED"/>
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
<!-- Broadcast receiver that will be notified to reset notifications -->
|
||||
<receiver
|
||||
android:name=".receiver.NotificationReceiver"
|
||||
android:exported="false">
|
||||
</receiver>
|
||||
|
||||
<!-- Broadcast receiver that will be notified for ActionService alarms. -->
|
||||
<receiver
|
||||
android:name=".datamodel.action.ActionServiceImpl$PendingActionReceiver"
|
||||
android:exported="false">
|
||||
<intent-filter>
|
||||
<action android:name="com.android.messaging.datamodel.PENDING_ACTION" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
<receiver android:name=".receiver.DefaultSmsSubscriptionChangeReceiver"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.telephony.action.DEFAULT_SMS_SUBSCRIPTION_CHANGED"/>
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
<!-- Widget that displays the conversation list -->
|
||||
<receiver android:name=".widget.BugleWidgetProvider"
|
||||
android:exported="true"
|
||||
android:label="@string/widget_conversation_name">
|
||||
<intent-filter>
|
||||
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
|
||||
</intent-filter>
|
||||
<meta-data android:name="android.appwidget.provider"
|
||||
android:resource="@xml/widget_conversation_list" />
|
||||
</receiver>
|
||||
|
||||
<!-- Widget that displays the messages of a single conversation -->
|
||||
<receiver android:name=".widget.WidgetConversationProvider"
|
||||
android:exported="true"
|
||||
android:label="@string/widget_conversation_name">
|
||||
<intent-filter>
|
||||
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
|
||||
</intent-filter>
|
||||
<meta-data android:name="android.appwidget.provider"
|
||||
android:resource="@xml/widget_conversation" />
|
||||
</receiver>
|
||||
|
||||
<service android:name=".widget.WidgetConversationListService"
|
||||
android:permission="android.permission.BIND_REMOTEVIEWS"
|
||||
android:exported="false" />
|
||||
|
||||
<service android:name=".widget.WidgetConversationService"
|
||||
android:permission="android.permission.BIND_REMOTEVIEWS"
|
||||
android:exported="false" />
|
||||
|
||||
<activity android:name=".ui.WidgetPickConversationActivity"
|
||||
android:theme="@style/BugleTheme"
|
||||
android:exported="true"
|
||||
android:label="@string/app_name" >
|
||||
<intent-filter>
|
||||
<action android:name="android.appwidget.action.APPWIDGET_CONFIGURE" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<service android:name="androidx.appcompat.mms.MmsService"/>
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
43
CleanSpec.mk
Normal file
@@ -0,0 +1,43 @@
|
||||
# Copyright (C) 2017 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.
|
||||
#
|
||||
|
||||
# If you don't need to do a full clean build but would like to touch
|
||||
# a file or delete some intermediate files, add a clean step to the end
|
||||
# of the list. These steps will only be run once, if they haven't been
|
||||
# run before.
|
||||
#
|
||||
# E.g.:
|
||||
# $(call add-clean-step, touch -c external/sqlite/sqlite3.h)
|
||||
# $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/STATIC_LIBRARIES/libz_intermediates)
|
||||
#
|
||||
# Always use "touch -c" and "rm -f" or "rm -rf" to gracefully deal with
|
||||
# files that are missing or have been moved.
|
||||
#
|
||||
# Use $(PRODUCT_OUT) to get to the "out/target/product/blah/" directory.
|
||||
# Use $(OUT_DIR) to refer to the "out" directory.
|
||||
#
|
||||
# If you need to re-do something that's already mentioned, just copy
|
||||
# the command and add it to the bottom of the list. E.g., if a change
|
||||
# that you made last week required touching a file and a change you
|
||||
# made today requires touching the same file, just copy the old
|
||||
# touch step and add it to the end of the list.
|
||||
#
|
||||
# ************************************************
|
||||
# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
|
||||
# ************************************************
|
||||
|
||||
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/app/messaging)
|
||||
$(call add-clean-step, rm -f $(PRODUCT_OUT)/system/lib/libgiftranscode.so)
|
||||
$(call add-clean-step, rm -f $(PRODUCT_OUT)/system/lib64/libgiftranscode.so)
|
||||
40
ForceProguard.mk
Executable file
@@ -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.
|
||||
|
||||
# Check to see if we need to force proguard to re-run, typically after using tapas to
|
||||
# switch to/from eng builds. This is determined by comparing the flag files used in the previous
|
||||
# build. If the flag files have changed, proguard is rerun.
|
||||
|
||||
# If the LOCAL_MODULE being setup isn't a build target, then don't run ForceProguard.
|
||||
ifneq (,$(findstring $(LOCAL_MODULE), $(TARGET_BUILD_APPS)))
|
||||
|
||||
PREVIOUS_FLAG_FILES_USED_DIR := $(call local-intermediates-dir,1)
|
||||
|
||||
# If the local intermediates dir doesn't exist, ForceProguard won't work.
|
||||
ifneq ($(wildcard $(PREVIOUS_FLAG_FILES_USED_DIR)),)
|
||||
PREVIOUS_FLAG_FILES_USED_FILE := $(PREVIOUS_FLAG_FILES_USED_DIR)/previous_proguard_flag_files
|
||||
PREVIOUS_FLAG_FILES_USED := $(if $(wildcard $(PREVIOUS_FLAG_FILES_USED_FILE)), \
|
||||
$(shell cat $(PREVIOUS_FLAG_FILES_USED_FILE)))
|
||||
|
||||
ifneq ($(strip $(PREVIOUS_FLAG_FILES_USED)), $(strip $(LOCAL_PROGUARD_FLAG_FILES)))
|
||||
$(info *** Flag files used for proguard have changed; forcing proguard to rerun.)
|
||||
$(shell touch $(LOCAL_PATH)/proguard.flags)
|
||||
$(shell echo $(LOCAL_PROGUARD_FLAG_FILES) > $(PREVIOUS_FLAG_FILES_USED_FILE))
|
||||
endif
|
||||
|
||||
endif
|
||||
# End local intermediates directory existence check
|
||||
|
||||
endif
|
||||
# End LOCAL_MODULE is a build target check
|
||||
4
OWNERS
Normal file
@@ -0,0 +1,4 @@
|
||||
# Default code reviewers picked from top 3 or more developers.
|
||||
# Please update this list if you find better candidates.
|
||||
tomtaylor@google.com
|
||||
rtenneti@google.com
|
||||
2
README
Normal file
@@ -0,0 +1,2 @@
|
||||
This app is not actively supported and the source is only available as a reference. This project will be removed from the source manifest sometime in the future.
|
||||
|
||||
666
assets/licenses.html
Normal file
@@ -0,0 +1,666 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>
|
||||
</title>
|
||||
<style>
|
||||
body { font-family: sans-serif; }
|
||||
pre { background-color: #eeeeee; padding: 1em; white-space: pre-wrap; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h3>Notice for AOSP:</h3>
|
||||
<pre>
|
||||
Copyright (c) 2005-2008, 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.
|
||||
|
||||
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.
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
</pre>
|
||||
|
||||
<h3>Notices for Guava: Google Core Libraries for Java</h3>
|
||||
<pre>
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
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.
|
||||
</pre>
|
||||
|
||||
<h3>Notices for JSR 305</h3>
|
||||
<pre>
|
||||
Copyright (c) 2007-2009, JSR305 expert group
|
||||
All rights reserved.
|
||||
|
||||
http://www.opensource.org/licenses/bsd-license.php
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
* Neither the name of the JSR305 expert group nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
</pre>
|
||||
|
||||
<h3>Notices for libphonenumber</h3>
|
||||
<pre>
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
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.
|
||||
</pre>
|
||||
|
||||
<h3>Notices for GIFLIB</h3>
|
||||
<pre>
|
||||
The GIFLIB distribution is Copyright (c) 1997 Eric S. Raymond
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
</pre>
|
||||
</body></html>
|
||||
40
jni/Android.bp
Normal file
@@ -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,
|
||||
}
|
||||
583
jni/GifTranscoder.cpp
Normal file
@@ -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 <jni.h>
|
||||
#include <time.h>
|
||||
#include <stdio.h>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include <android/log.h>
|
||||
|
||||
#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 <typename T>
|
||||
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<GifByteType> srcBuffer(gifIn->SWidth * gifIn->SHeight);
|
||||
|
||||
// Buffer for rendering images from the input GIF.
|
||||
std::unique_ptr<ColorARGB[]> renderBuffer(new ColorARGB[gifIn->SWidth * gifIn->SHeight]);
|
||||
|
||||
// Buffer for writing new images to output GIF (one row at a time).
|
||||
std::unique_ptr<GifByteType[]> 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<void**>(&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;
|
||||
}
|
||||
122
jni/GifTranscoder.h
Normal file
@@ -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 <sys/types.h>
|
||||
|
||||
#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
|
||||
26
proguard-release.flags
Normal file
@@ -0,0 +1,26 @@
|
||||
# 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.
|
||||
|
||||
-keep class com.android.messaging.ui.contact.* { *; }
|
||||
|
||||
-assumenosideeffects public class com.android.messaging.util.Trace {
|
||||
public void beginSection(...);
|
||||
public void endSection(...);
|
||||
}
|
||||
-assumenosideeffects public class com.android.messaging.util.Assert {
|
||||
private void setIfEngBuild();
|
||||
}
|
||||
-assumenosideeffects public class com.android.messaging.util.DebugUtils {
|
||||
public void logCurrentMethod(...);
|
||||
}
|
||||
41
proguard-test.flags
Executable file
@@ -0,0 +1,41 @@
|
||||
# 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.
|
||||
#
|
||||
# These flags are in addition to the one in proguard.flags, which is included by the build
|
||||
# directives in Android.mk.
|
||||
|
||||
-dontobfuscate
|
||||
-dontoptimize
|
||||
|
||||
# FLAG(dnotario): Until we rationalize how to handle tests (extensive unit tests will want similar
|
||||
# settings to these, but maybe we want to require VisibleForTesting attribute), just expose all
|
||||
# non-private methods. This means we cannot run tests on user builds for the moment.
|
||||
-keep class com.android.messaging.* {
|
||||
!private *;
|
||||
}
|
||||
|
||||
-keep class com.android.messaging.*.* {
|
||||
!private *;
|
||||
}
|
||||
|
||||
-keep class com.android.messaging.*.*.* {
|
||||
!private *;
|
||||
}
|
||||
|
||||
-keep class com.android.messaging.ui.*.* { *; }
|
||||
|
||||
# Keep the classes needed by emma
|
||||
-keep class com.vladium.** { *; }
|
||||
|
||||
# End of Test Rules
|
||||
64
proguard.flags
Normal file
@@ -0,0 +1,64 @@
|
||||
# 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.
|
||||
#
|
||||
# Keep enough data for stack traces
|
||||
-renamesourcefileattribute SourceFile
|
||||
-keepattributes SourceFile,LineNumberTable,*Annotation*
|
||||
|
||||
# Keep classes and methods that have the guava @VisibleForTesting annotation
|
||||
-keep @com.google.common.annotations.VisibleForTesting class *
|
||||
-keepclassmembers class * {
|
||||
@com.google.common.annotations.VisibleForTesting *;
|
||||
}
|
||||
-keep class com.android.messaging.* { *; }
|
||||
-keep class com.android.messaging.*.* { *; }
|
||||
-keep class com.android.messaging.*.*.* { *; }
|
||||
|
||||
# Keep methods that have the @VisibleForAnimation annotation
|
||||
-keep @interface com.android.messaging.annotation.VisibleForAnimation
|
||||
-keepclassmembers class * {
|
||||
@com.android.messaging.annotation.VisibleForAnimation *;
|
||||
}
|
||||
|
||||
-keep public class * extends android.app.Activity
|
||||
-keep public class * extends android.app.Application
|
||||
-keep public class * extends android.app.Service
|
||||
-keep public class * extends android.content.BroadcastReceiver
|
||||
-keep public class * extends android.content.ContentProvider
|
||||
-keep public class * extends android.app.backup.BackupAgentHelper
|
||||
-keep public class * extends android.preference.Preference
|
||||
-keep public class * extends androidx.fragment.app.Fragment
|
||||
-keep public class com.android.vcard.* { *; }
|
||||
|
||||
-keep class androidx.collection.* { *; }
|
||||
-keep class androidx.core.* { *; }
|
||||
-keep class androidx.core.*.* { *; }
|
||||
-keep class androidx.appcompat.* { *; }
|
||||
-keep class androidx.appcompat.*.* { *; }
|
||||
-keep class androidx.recyclerview.widget.* { *; }
|
||||
-keep class androidx.viewpager.widget.* { *; }
|
||||
|
||||
# Keep rastermill classes that need to be accessed from native code (JNI)
|
||||
-keep class android.support.rastermill.** { *; }
|
||||
|
||||
# Preserve the name of the getCaller method so it can find itself in the stack trace it generates
|
||||
-keepclassmembers public class com.android.messaging.util.DebugUtils {
|
||||
public static java.lang.StackTraceElement getCaller(...);
|
||||
}
|
||||
|
||||
# Keep the static fields of referenced inner classes of auto-generated R classes, in case we
|
||||
# access those fields by reflection (e.g. EmojiMarkup)
|
||||
-keepclassmembers class **.R$* {
|
||||
public static <fields>;
|
||||
}
|
||||
37
res/animator/fab_anim.xml
Normal file
@@ -0,0 +1,37 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<item
|
||||
android:state_enabled="true"
|
||||
android:state_pressed="true">
|
||||
<objectAnimator
|
||||
android:duration="@android:integer/config_shortAnimTime"
|
||||
android:propertyName="translationZ"
|
||||
android:valueTo="@dimen/fab_elevation_pressed"
|
||||
android:valueType="floatType" />
|
||||
</item>
|
||||
|
||||
<item>
|
||||
<objectAnimator
|
||||
android:duration="@android:integer/config_shortAnimTime"
|
||||
android:propertyName="translationZ"
|
||||
android:valueTo="@dimen/fab_elevation"
|
||||
android:valueType="floatType" />
|
||||
</item>
|
||||
|
||||
</selector>
|
||||
23
res/color/tab_text_color.xml
Normal file
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item
|
||||
android:color="@android:color/white"
|
||||
android:state_selected="true"/>
|
||||
<item
|
||||
android:color="@color/translucent_white" />
|
||||
</selector>
|
||||
BIN
res/drawable-hdpi/contact_popup_background.9.png
Normal file
|
After Width: | Height: | Size: 149 B |
BIN
res/drawable-hdpi/fab_new_message_static_shadow.png
Normal file
|
After Width: | Height: | Size: 2.1 KiB |
BIN
res/drawable-hdpi/ic_add_white.png
Normal file
|
After Width: | Height: | Size: 370 B |
BIN
res/drawable-hdpi/ic_archive_small_dark.png
Normal file
|
After Width: | Height: | Size: 983 B |
BIN
res/drawable-hdpi/ic_archive_undo_small_dark.png
Normal file
|
After Width: | Height: | Size: 983 B |
BIN
res/drawable-hdpi/ic_arrow_back_light.png
Normal file
|
After Width: | Height: | Size: 644 B |
BIN
res/drawable-hdpi/ic_attachment_dark.png
Normal file
|
After Width: | Height: | Size: 975 B |
BIN
res/drawable-hdpi/ic_audio_light.png
Normal file
|
After Width: | Height: | Size: 965 B |
BIN
res/drawable-hdpi/ic_audio_pause.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
res/drawable-hdpi/ic_audio_play.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
res/drawable-hdpi/ic_camera_front_light.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
res/drawable-hdpi/ic_camera_light.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
res/drawable-hdpi/ic_camera_rear_light.png
Normal file
|
After Width: | Height: | Size: 935 B |
BIN
res/drawable-hdpi/ic_cancel_small_dark.png
Normal file
|
After Width: | Height: | Size: 655 B |
BIN
res/drawable-hdpi/ic_cancel_small_light.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
res/drawable-hdpi/ic_checkbox_blank_light.png
Normal file
|
After Width: | Height: | Size: 423 B |
BIN
res/drawable-hdpi/ic_checkbox_light.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
res/drawable-hdpi/ic_checkbox_outline_light.png
Normal file
|
After Width: | Height: | Size: 1.0 KiB |
BIN
res/drawable-hdpi/ic_checkmark_circle_blue.png
Normal file
|
After Width: | Height: | Size: 2.3 KiB |
BIN
res/drawable-hdpi/ic_checkmark_large.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
res/drawable-hdpi/ic_checkmark_large_light.png
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
BIN
res/drawable-hdpi/ic_checkmark_small_light.png
Normal file
|
After Width: | Height: | Size: 626 B |
BIN
res/drawable-hdpi/ic_content_copy_dark.png
Normal file
|
After Width: | Height: | Size: 817 B |
BIN
res/drawable-hdpi/ic_delete_small_dark.png
Normal file
|
After Width: | Height: | Size: 763 B |
BIN
res/drawable-hdpi/ic_dnd_on_dark.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
res/drawable-hdpi/ic_failed_light.png
Normal file
|
After Width: | Height: | Size: 501 B |
BIN
res/drawable-hdpi/ic_failed_status_red.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
res/drawable-hdpi/ic_file_download_dark.png
Normal file
|
After Width: | Height: | Size: 799 B |
BIN
res/drawable-hdpi/ic_file_download_light.png
Normal file
|
After Width: | Height: | Size: 755 B |
BIN
res/drawable-hdpi/ic_forward_dark.png
Normal file
|
After Width: | Height: | Size: 714 B |
BIN
res/drawable-hdpi/ic_image_light.png
Normal file
|
After Width: | Height: | Size: 863 B |
BIN
res/drawable-hdpi/ic_ime_light.png
Normal file
|
After Width: | Height: | Size: 893 B |
BIN
res/drawable-hdpi/ic_info_dark.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
res/drawable-hdpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 2.2 KiB |
BIN
res/drawable-hdpi/ic_mp_audio_mic.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
res/drawable-hdpi/ic_mp_camera_small_light.png
Normal file
|
After Width: | Height: | Size: 2.0 KiB |
BIN
res/drawable-hdpi/ic_mp_capture_stop_large_light.png
Normal file
|
After Width: | Height: | Size: 8.1 KiB |
BIN
res/drawable-hdpi/ic_mp_full_screen_light.png
Normal file
|
After Width: | Height: | Size: 2.0 KiB |
BIN
res/drawable-hdpi/ic_mp_video_large_light.png
Normal file
|
After Width: | Height: | Size: 2.0 KiB |
BIN
res/drawable-hdpi/ic_mp_video_small_light.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
res/drawable-hdpi/ic_music.png
Normal file
|
After Width: | Height: | Size: 326 B |
BIN
res/drawable-hdpi/ic_notifications_off_dark.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
res/drawable-hdpi/ic_notifications_off_light.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
res/drawable-hdpi/ic_notifications_off_small_light.png
Normal file
|
After Width: | Height: | Size: 839 B |
BIN
res/drawable-hdpi/ic_notifications_on_dark.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
res/drawable-hdpi/ic_notifications_on_light.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
res/drawable-hdpi/ic_numeric_dialpad.png
Normal file
|
After Width: | Height: | Size: 626 B |
BIN
res/drawable-hdpi/ic_oobe_conv_list.png
Normal file
|
After Width: | Height: | Size: 4.8 KiB |
BIN
res/drawable-hdpi/ic_oobe_freq_list.png
Normal file
|
After Width: | Height: | Size: 4.2 KiB |
BIN
res/drawable-hdpi/ic_people_add_light.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
res/drawable-hdpi/ic_person_add_dark.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
res/drawable-hdpi/ic_person_add_light.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
res/drawable-hdpi/ic_person_light.png
Normal file
|
After Width: | Height: | Size: 906 B |
BIN
res/drawable-hdpi/ic_person_light_large.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
res/drawable-hdpi/ic_phone_small_light.png
Normal file
|
After Width: | Height: | Size: 1005 B |
BIN
res/drawable-hdpi/ic_photo_library_light.png
Normal file
|
After Width: | Height: | Size: 468 B |
BIN
res/drawable-hdpi/ic_preview_pause.png
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
res/drawable-hdpi/ic_preview_play.png
Normal file
|
After Width: | Height: | Size: 3.6 KiB |
BIN
res/drawable-hdpi/ic_remove_light.png
Normal file
|
After Width: | Height: | Size: 3.2 KiB |
BIN
res/drawable-hdpi/ic_remove_small_light.png
Normal file
|
After Width: | Height: | Size: 712 B |
BIN
res/drawable-hdpi/ic_save_dark.png
Normal file
|
After Width: | Height: | Size: 947 B |
BIN
res/drawable-hdpi/ic_save_light.png
Normal file
|
After Width: | Height: | Size: 913 B |
BIN
res/drawable-hdpi/ic_send_dark.png
Normal file
|
After Width: | Height: | Size: 1.0 KiB |
BIN
res/drawable-hdpi/ic_send_light.png
Normal file
|
After Width: | Height: | Size: 1.0 KiB |
BIN
res/drawable-hdpi/ic_share_dark.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
res/drawable-hdpi/ic_share_light.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
res/drawable-hdpi/ic_sim_card_send.png
Normal file
|
After Width: | Height: | Size: 488 B |
BIN
res/drawable-hdpi/ic_sms_delivery_ok.png
Normal file
|
After Width: | Height: | Size: 545 B |
BIN
res/drawable-hdpi/ic_sms_light.png
Normal file
|
After Width: | Height: | Size: 933 B |
BIN
res/drawable-hdpi/ic_sms_multi_light.png
Normal file
|
After Width: | Height: | Size: 926 B |
BIN
res/drawable-hdpi/ic_video_play_light.png
Normal file
|
After Width: | Height: | Size: 3.9 KiB |
BIN
res/drawable-hdpi/ic_wear_reply.png
Normal file
|
After Width: | Height: | Size: 1.7 KiB |
BIN
res/drawable-hdpi/ic_widget_avatar_shadow.png
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
res/drawable-hdpi/ic_widget_list.png
Normal file
|
After Width: | Height: | Size: 733 B |
BIN
res/drawable-hdpi/ic_work_profile.png
Normal file
|
After Width: | Height: | Size: 158 B |
BIN
res/drawable-hdpi/msg_bubble_error.9.png
Normal file
|
After Width: | Height: | Size: 529 B |
BIN
res/drawable-hdpi/msg_bubble_incoming.9.png
Normal file
|
After Width: | Height: | Size: 469 B |
BIN
res/drawable-hdpi/msg_bubble_input.9.png
Normal file
|
After Width: | Height: | Size: 394 B |
BIN
res/drawable-hdpi/msg_bubble_outgoing.9.png
Normal file
|
After Width: | Height: | Size: 472 B |
BIN
res/drawable-hdpi/permissions.png
Normal file
|
After Width: | Height: | Size: 22 KiB |
BIN
res/drawable-hdpi/swipe_shadow.9.png
Normal file
|
After Width: | Height: | Size: 194 B |
BIN
res/drawable-hdpi/swipe_shadow_drag.9.png
Normal file
|
After Width: | Height: | Size: 168 B |
BIN
res/drawable-hdpi/tab_btn_bg_normal.9.png
Normal file
|
After Width: | Height: | Size: 164 B |
BIN
res/drawable-hdpi/tab_btn_bg_pressed.9.png
Normal file
|
After Width: | Height: | Size: 164 B |
BIN
res/drawable-hdpi/tab_selected.9.png
Normal file
|
After Width: | Height: | Size: 145 B |