Compare commits

...

3 commits

Author SHA1 Message Date
maelstrom ae7b361482 Much debugging later... 2024-08-20 01:24:18 +02:00
maelstrom ab484a0350 Rewrote patcher.py 2024-08-20 00:58:17 +02:00
maelstrom 6a50a4fc4f ............. fuck 2024-08-20 00:58:00 +02:00
11 changed files with 166 additions and 568 deletions

2
.vscode/launch.json vendored
View file

@ -8,7 +8,7 @@
"name": "Python Debugger: Current File",
"type": "debugpy",
"request": "launch",
"program": "test.py",
"program": "buildtool/build.py",
"console": "integratedTerminal"
}
]

View file

@ -1,2 +1,4 @@
Implement smali patches + migrate all smali code to patches
Implement Java stack
Implement Java stack
Fix weird bug where it sometimes thinks changes have been made even though there have not been, thus causing the APK to be reassambled unnecessarily.

View file

@ -31,7 +31,7 @@ range_anchor: "@$" IDENTIFIER
STRING: /"([^"\\]|\\.)*"/
RAW_STRING: /'[^']*'/
LONG_STRING: /<<\s*(?P<terminator>[^\n]+)\n.*\n(?P=terminator)/s
LONG_STRING: /<<\s*(?P<terminator>[^\n]+)\n.*?\n(?P=terminator)/s
LINE_NUMBER: /ln\d+/
CHAR_INDEX: /ch\d+/
LINE_COLUMN: /ln\d+c\d+/

View file

@ -1,12 +1,48 @@
from pathlib import Path
from lark import Lark
from lark.lexer import Token
from lark.tree import Branch
from dataclasses import dataclass
import os
import re
@dataclass
class LineColumn:
line: int
column: int
@dataclass
class CharIndex:
char: int
type Location = LineColumn | CharIndex
@dataclass
class InsertionAction:
content: str
location: Location
@dataclass
class RegexReplaceAction:
...
type PatchAction = InsertionAction | RegexReplaceAction
@dataclass
class Patch:
target: Path
actions: list[PatchAction]
@dataclass
class PatchFile:
patches: list[Patch]
modified: float
def parse_string(token: Token):
assert isinstance(token.value, str)
if token.type == 'STRING':
string = token.value[1:-1]
string = re.sub(r"\\n","\n", string)
@ -21,19 +57,19 @@ def parse_string(token: Token):
string = re.match(re.compile(r"<<\s*(?P<terminator>[^\n]+)\n(.*)\n(?P=terminator)", re.MULTILINE + re.DOTALL),token.value)
assert string is not None
string = string.group(2)
return string
return str(string)
else:
raise ValueError()
def parse_location(location: Token):
assert isinstance(location.value, str)
m = re.match(r"ln([0-9]+)(?:c([0-9]+))?", location.value)
if m:
ln, col = m.groups()
return {"type": "lncol", "line": int(ln), "column": int(col) if col else 0}
if location[:2] == "ln":
line, column = re.match(r"ln([0-9]+)(?:c([0-9]+))?", location.value).groups()
return LineColumn(int(line), int(column or '1'))
m = re.match(r"ch([0-9]+)", location.value)
if m:
ch = m.groups()[0]
return {"type": "char", "index": int(ch)}
if location[:2] == "ch":
char = re.match(r"ch([0-9]+)", location.value).groups()[0]
return CharIndex(int(char))
raise RuntimeError("Cannot parse location")
@ -41,15 +77,15 @@ def parse_patch(branch: Branch[Token], mtime: float):
# First instruction is always file declaration
target_file = parse_string(branch.children[0].children[0]) # pyright: ignore[reportUnknownMemberType, reportArgumentType]
actions = []
actions: list[PatchAction] = []
for inst in branch.children[1:]:
match inst.data:
case "insert":
actions.append({"type": "insert", "at": parse_location(inst.children[0]), "content": parse_string(inst.children[1])})
actions.append(InsertionAction(location=parse_location(inst.children[0]), content=parse_string(inst.children[1])))
# print(f"Inserting {parse_string(inst.children[1])} at {inst.children[0]} in {target_file}")
return {"target": target_file, "actions": actions, "timestamp": mtime}
return Patch(target=Path(target_file), actions=actions)
def parse_patch_file(file: str):
lark = Lark.open('grammar.lark', rel_to=__file__)

View file

@ -1,72 +1,103 @@
from .parser import parse_patch_file
from dataclasses import dataclass
from typing import Any
from .parser import CharIndex, InsertionAction, PatchAction, Location, parse_patch_file
from pathlib import Path
from task.util import *
def resolve_position(location, src: str):
if location["type"] == "char":
return location["index"]
elif location["type"] == "lncol":
j = 0
for i, x in enumerate(src.split('\n')):
if (i+1) == location["line"]:
if location["column"] > len(x):
print(f"Cannot insert at line {location['line']} column {location['column']}. The line is not that long.")
exit(-1)
return j + location["column"]
j += len(x) + 1
print(f"Cannot insert at line {location['line']}. The file is not long enough.")
exit(-1)
def read_insertion(action, src):
position = resolve_position(action["at"], src)
return {"content": action["content"], "pos": position}
def process_patch_file(patch_file: str, check_date: bool = True):
patches = parse_patch_file(patch_file)
# Converts nebulous locations to real positions
def evaluate_position(content: str, location: Location):
if isinstance(location, CharIndex):
return location.char
for patch in patches:
target_src = EXTRACTED_DIR / patch["target"]
target_dest = PATCHED_RSC_DIR / patch["target"]
# Ineligent yet effective solution...
chars_read = 0
if location.line > len(content.split('\n')):
raise RuntimeError("Line number out of range")
for i, line in enumerate(content.split('\n')):
if location.line == i + 1:
if location.column > len(line):
raise RuntimeError("Column number out of range")
# Skip old patches
if check_date and target_dest.exists() and target_dest.stat().st_mtime > patch["timestamp"]:
print(f"Skipping patch {patch['target']}...")
return chars_read + location.column - 1
chars_read += len(line) + 1 # Don't forget the newline character!!!
raise RuntimeError("Line number out of range")
@dataclass
class ProcessedInsertion:
position: int
content: str
patch_file_name: str
type ProcessedAction = ProcessedInsertion
def update_positions_of_patches(actions: list[ProcessedAction], at: int, by: int):
for action in actions:
if action.position < at:
continue
print(f"Patching {patch['target']} with {len(patch['actions'])} actions")
# Read the source of the file
with open(target_src, 'r') as f:
src = f.read()
# Resolve the actual char locations in the patches
insertions = [read_insertion(action, src) for action in patch["actions"]]
insertions = [x for x in insertions if x is not None]
for insertion in insertions:
src = src[:insertion["pos"]] + insertion["content"] + src[insertion["pos"]:]
action.position += by
# Correct insertions that follow this one
for i2 in insertions:
# Only update insertions that come *after* this one
if i2 == insertion or i2["pos"] < insertion["pos"]:
continue
i2["pos"] += len(insertion["content"])
# Make parent dirs
target_dest.parent.mkdir(parents=True, exist_ok=True)
# Write the changed output
with open(target_dest, 'w') as f:
f.write(src)
def process_all_patches(dir: Path | str, check_date: bool = True):
dir = Path(dir)
patches: dict[Path, list[ProcessedAction]] = {}
# First, we collect all actions from all patches in each patch file
for patch_file in dir.rglob("*.patch"):
print("Processing patch {}".format(patch_file.relative_to(dir)))
process_patch_file(str(patch_file), check_date=check_date)
pfrn = patch_file.relative_to(dir)
for patch in parse_patch_file(str(patch_file)):
patches[patch.target] = patches.get(patch.target, [])
src_file = EXTRACTED_DIR / patch.target
dest_file = PATCHED_RSC_DIR / patch.target
for action in patch.actions:
# Skip patch if it is older than the target file
if dest_file.exists() and src_file.stat().st_mtime <= dest_file.stat().st_mtime:
print(f"Skipped {pfrn}::{patch.target}")
continue
with open(src_file, 'r') as f:
content = f.read()
# We also consider the true position of each insertion, too
if isinstance(action, InsertionAction):
processed_action = ProcessedInsertion(position=evaluate_position(content, action.location), content=action.content, patch_file_name=str(pfrn))
else:
raise RuntimeError("I don't know how to deal with those kinds of patches")
patches[patch.target].append(processed_action)
# Now we actually do all the patching
for target_file, actions in patches.items():
src_file = EXTRACTED_DIR / target_file
dest_file = PATCHED_RSC_DIR / target_file
with open(src_file, 'r') as f:
content = f.read()
print(f"Processing patches for: {target_file}")
for action in actions:
if isinstance(action, ProcessedInsertion):
# Update the positions of patches which modify after this one, so that their position isn't scrambled by this one
position = action.position
# update_positions_of_patches(actions, position, len(action.content))
# Update content
content = content[:position] + action.content + content[position:]
print(f" |- {action.patch_file_name}")
else:
raise RuntimeError("I don't know how to deal with those kinds of patches")
# Commit changes
dest_file.parent.mkdir(parents=True, exist_ok=True)
with open(dest_file, 'w') as f:
_ = f.write(content)

View file

@ -6,12 +6,17 @@ import subprocess
def assemble_apk():
updated = merge_resources()
print(f"IS UPDATED: {updated}")
if not updated and Path(ASSEMBLED_APK).exists():
print("Skipping assembly")
return False
# Assemble
print("Assembling APK...")
_ = subprocess.run([JAVA_BIN, '-jar', APKTOOL, 'b', MERGED_RSC_DIR, '-o', ASSEMBLED_APK])
res = subprocess.run([JAVA_BIN, '-jar', APKTOOL, 'b', MERGED_RSC_DIR, '-o', ASSEMBLED_APK])
if res.returncode != 0:
print("Error ocurred while assembling")
exit(res.returncode)
return True

View file

@ -23,9 +23,11 @@ def merge_resources():
updated = first_time
# Make sure to place "or updated" *after* the statement, not before, because 'and' and 'or' are short-circuting... ya idiot
print("Merging patched resources...")
updated = updated or fileutil.merge_into(PATCHED_RSC_DIR, MERGED_RSC_DIR, check_date=not first_time)
updated = fileutil.merge_into(PATCHED_RSC_DIR, MERGED_RSC_DIR, check_date=not first_time) or updated
print("Merging dex files...")
updated = updated or fileutil.merge_into(COMPILED_SMALI_DIR, MERGED_RSC_DIR, check_date=not first_time)
updated = fileutil.merge_into(COMPILED_SMALI_DIR, MERGED_RSC_DIR, check_date=not first_time) or updated
return updated

View file

@ -15,7 +15,10 @@ def align_apk():
# Align the APK
print("Aligning APK...")
ALIGNED_APK.parent.mkdir(exist_ok=True)
_ = subprocess.run([ZIPALIGN, '-pvf', '4', ASSEMBLED_APK, ALIGNED_APK])
res = subprocess.run([ZIPALIGN, '-pvf', '4', ASSEMBLED_APK, ALIGNED_APK])
if res.returncode != 0:
print("Error ocurred while aligning")
exit(res.returncode)
def sign_apk():
updated = align_apk()

1
requirements.txt Normal file
View file

@ -0,0 +1 @@
lark==1.2.2

View file

@ -5,4 +5,13 @@ file 'res/layout/fragment_blog_settings.xml'
insert ln10 << @end
<com.tumblr.ui.widget.TMBlogSettingsTextRow android:id="@id/ykit_settings" tumblr:listItemDetail="Change settings for YKit" tumblr:listItemTitle="YKit Settings" style="@style/DetailedListItem" />
@end
# Registers the Ykit Settings activity
file 'AndroidManifest.xml'
insert ln489 << @end
<activity android:label="YKit Settings" android:name="dev.maelstrom.ykit.settings.YkitSettingsActivity" android:screenOrientation="portrait" android:theme="@style/Theme.Tumblr.SolidActionBar.PushSettings"/>
@end

View file

@ -1,491 +0,0 @@
<?xml version="1.0" encoding="utf-8" standalone="no"?><manifest xmlns:android="http://schemas.android.com/apk/res/android" android:compileSdkVersion="34" android:compileSdkVersionCodename="14" package="com.tumblr" platformBuildVersionCode="34" platformBuildVersionName="14">
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.READ_SYNC_SETTINGS"/>
<uses-permission android:name="android.permission.WRITE_SYNC_SETTINGS"/>
<uses-permission android:name="android.permission.READ_CONTACTS"/>
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<uses-permission android:name="com.google.android.gms.permission.AD_ID"/>
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES"/>
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO"/>
<uses-permission android:maxSdkVersion="32" android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
<uses-feature android:name="android.hardware.camera" android:required="false"/>
<uses-feature android:name="android.hardware.camera.autofocus" android:required="false"/>
<uses-feature android:name="android.hardware.camera.front" android:required="false"/>
<uses-feature android:name="android.hardware.wifi" android:required="false"/>
<uses-feature android:name="android.hardware.screen.portrait" android:required="false"/>
<uses-feature android:name="android.hardware.TOUCHSCREEN" android:required="false"/>
<permission android:name="com.tumblr.permissions.RECEIVER" android:protectionLevel="signature"/>
<uses-permission android:name="com.tumblr.permissions.RECEIVER"/>
<queries>
<package android:name="com.ideashower.readitlater.pro"/>
<intent>
<action android:name="android.intent.action.SEND"/>
<data android:mimeType="text/plain"/>
</intent>
<intent>
<action android:name="android.intent.action.VIEW"/>
<data android:scheme="otpauth"/>
</intent>
<package android:name="com.android.vending"/>
<package android:name="com.google.android.engage.verifyapp"/>
<intent>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.BROWSABLE"/>
<data android:scheme="https"/>
</intent>
<intent>
<action android:name="android.support.customtabs.action.CustomTabsService"/>
</intent>
<package android:name="com.facebook.katana"/>
<intent>
<action android:name="com.android.vending.billing.InAppBillingService.BIND"/>
</intent>
</queries>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK"/>
<uses-permission android:name="android.permission.ACCESS_ADSERVICES_AD_ID"/>
<uses-permission android:name="android.permission.ACCESS_ADSERVICES_ATTRIBUTION"/>
<uses-permission android:name="android.permission.ACCESS_ADSERVICES_TOPICS"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="com.android.vending.BILLING"/>
<permission android:name="com.tumblr.DYNAMIC_RECEIVER_NOT_EXPORTED_PERMISSION" android:protectionLevel="signature"/>
<uses-permission android:name="com.tumblr.DYNAMIC_RECEIVER_NOT_EXPORTED_PERMISSION"/>
<uses-permission android:name="com.google.android.finsky.permission.BIND_GET_INSTALL_REFERRER_SERVICE"/>
<uses-permission android:name="com.sec.android.provider.badge.permission.READ"/>
<uses-permission android:name="com.sec.android.provider.badge.permission.WRITE"/>
<uses-permission android:name="com.htc.launcher.permission.READ_SETTINGS"/>
<uses-permission android:name="com.htc.launcher.permission.UPDATE_SHORTCUT"/>
<uses-permission android:name="com.sonyericsson.home.permission.BROADCAST_BADGE"/>
<uses-permission android:name="com.sonymobile.home.permission.PROVIDER_INSERT_BADGE"/>
<uses-permission android:name="com.anddoes.launcher.permission.UPDATE_COUNT"/>
<uses-permission android:name="com.majeur.launcher.permission.UPDATE_BADGE"/>
<uses-permission android:name="com.huawei.android.launcher.permission.CHANGE_BADGE"/>
<uses-permission android:name="com.huawei.android.launcher.permission.READ_SETTINGS"/>
<uses-permission android:name="com.huawei.android.launcher.permission.WRITE_SETTINGS"/>
<uses-permission android:name="android.permission.READ_APP_BADGE"/>
<uses-permission android:name="com.oppo.launcher.permission.READ_SETTINGS"/>
<uses-permission android:name="com.oppo.launcher.permission.WRITE_SETTINGS"/>
<uses-permission android:name="me.everything.badger.permission.BADGE_COUNT_READ"/>
<uses-permission android:name="me.everything.badger.permission.BADGE_COUNT_WRITE"/>
<application android:allowBackup="false" android:appComponentFactory="androidx.core.app.CoreComponentFactory" android:debuggable="true" android:extractNativeLibs="false" android:hardwareAccelerated="true" android:icon="@mipmap/ic_launcher" android:label="@string/tumblr_app_name" android:largeHeap="true" android:localeConfig="@xml/locales_config" android:name="com.tumblr.App" android:networkSecurityConfig="@xml/network_security_config" android:requestLegacyExternalStorage="true" android:supportsRtl="false" android:theme="@style/Theme.Tumblr" android:usesCleartextTraffic="true">
<profileable android:shell="true"/>
<activity android:name="com.tumblr.onboarding.OnboardingActivity" android:screenOrientation="portrait" android:theme="@style/Onboarding.Step"/>
<activity android:name="com.tumblr.onboarding.preonboarding.CombinedPreOnboardingActivity" android:screenOrientation="portrait" android:theme="@style/Onboarding"/>
<activity android:label="@string/third_party_auth_login_options" android:name="com.tumblr.onboarding.options.LoginOptionsActivity" android:screenOrientation="portrait" android:theme="@style/Theme.Tumblr.SolidActionBar.PushSettings"/>
<activity android:label="@string/settings_birthday" android:name="com.tumblr.onboarding.options.BirthdayOptionsActivity" android:screenOrientation="portrait" android:theme="@style/Theme.Tumblr.SolidActionBar.PushSettings"/>
<activity android:configChanges="orientation|screenSize" android:label="" android:name="com.tumblr.onboarding.signup.SignUpActivity" android:screenOrientation="portrait" android:theme="@style/Onboarding.Signup" android:windowSoftInputMode="adjustResize"/>
<activity android:label="@string/subscriptions_settings" android:name="com.tumblr.memberships.subscriptions.SubscriptionsActivity" android:screenOrientation="portrait" android:theme="@style/Theme.Tumblr.SolidActionBar"/>
<activity android:name="com.tumblr.memberships.WebCheckoutActivity" android:screenOrientation="portrait" android:theme="@style/Theme.Tumblr.NoActionBar.DarkStatusBar"/>
<activity android:name="com.tumblr.memberships.WebProvisionActivity" android:screenOrientation="portrait" android:theme="@style/Theme.Tumblr.NoActionBar.DarkStatusBar"/>
<activity android:name="com.tumblr.memberships.WebPaymentMethodActivity" android:screenOrientation="portrait" android:theme="@style/Theme.Tumblr.NoActionBar.DarkStatusBar"/>
<activity android:configChanges="keyboardHidden|orientation|screenSize" android:label="" android:name="com.tumblr.memberships.TipJarSetupCompleteActivity" android:screenOrientation="nosensor" android:theme="@style/Theme.Tumblr.NoActionBar.TipJar"/>
<activity android:label="@string/payouts_settings" android:name="com.tumblr.memberships.PayoutsActivity" android:screenOrientation="portrait" android:theme="@style/Theme.Tumblr.SolidActionBar.PushSettings"/>
<activity android:label="@string/tumblrmart" android:name="com.tumblr.tumblrmart.view.TumblrMartV2FrontStoreActivity" android:screenOrientation="portrait" android:theme="@style/Theme.Tumblr.NoActionBar.DarkStatusBar"/>
<activity android:label="@string/tumblrmart" android:name="com.tumblr.tumblrmart.view.ProductCheckoutActivity" android:screenOrientation="portrait" android:theme="@style/Theme.Tumblr.NoActionBar.DarkStatusBar"/>
<activity android:label="@string/tumblr_premium" android:name="com.tumblr.premiumold.purchase.PremiumPurchaseActivity" android:screenOrientation="portrait" android:theme="@style/Theme.Tumblr.NoActionBar.PremiumPerks"/>
<activity android:label="@string/tumblr_premium" android:name="com.tumblr.premiumold.purchase.GoAdFreeActivity" android:screenOrientation="portrait" android:theme="@style/Theme.Tumblr.NoActionBar.NoBackground"/>
<activity android:label="@string/tumblr_premium" android:name="com.tumblr.premiumold.settings.PremiumSettingsActivity" android:screenOrientation="portrait" android:theme="@style/Theme.Tumblr.SolidActionBar.PushSettings"/>
<activity android:label="@string/cancel_subscription" android:name="com.tumblr.premiumold.settings.PremiumCancellationActivity" android:screenOrientation="portrait" android:theme="@style/Theme.Tumblr.SolidActionBar.PushSettings"/>
<activity android:label="@string/adfree_cancellation_survey" android:name="com.tumblr.premiumold.settings.AdFreeCancellationSurveyActivity" android:screenOrientation="portrait" android:theme="@style/Theme.Tumblr.SolidActionBar.PushSettings"/>
<activity android:label="@string/gifts" android:name="com.tumblr.premiumold.gift.ManageGiftsActivity" android:screenOrientation="portrait" android:theme="@style/Theme.Tumblr.SolidActionBar.Dark"/>
<activity android:label="@string/payment_and_purchases" android:name="com.tumblr.premiumold.paymentandpurchases.PaymentAndPurchasesActivity" android:screenOrientation="portrait" android:theme="@style/Theme.Tumblr.SolidActionBar.Dark"/>
<activity android:name="com.tumblr.notes.view.PostNotesActivity" android:screenOrientation="portrait" android:theme="@style/Theme.Tumblr.NoActionBar" android:windowSoftInputMode="stateAlwaysHidden"/>
<activity android:name="com.tumblr.blaze.ui.done.BlazeInsightsActivity" android:screenOrientation="portrait"/>
<activity android:name="com.tumblr.blaze.ui.compose.BlazeEntryActivity" android:screenOrientation="portrait"/>
<provider android:authorities="com.tumblr.androidx-startup" android:exported="false" android:name="androidx.startup.InitializationProvider">
<meta-data android:name="com.tumblr.startup.WebviewInitializer" android:value="androidx.startup"/>
<meta-data android:name="com.tumblr.startup.NimbusInitializer" android:value="androidx.startup"/>
<meta-data android:name="com.tumblr.startup.RememberInitializer" android:value="androidx.startup"/>
<meta-data android:name="androidx.emoji2.text.EmojiCompatInitializer" android:value="androidx.startup"/>
<meta-data android:name="androidx.lifecycle.ProcessLifecycleInitializer" android:value="androidx.startup"/>
<meta-data android:name="androidx.profileinstaller.ProfileInstallerInitializer" android:value="androidx.startup"/>
</provider>
<activity android:configChanges="orientation|screenSize" android:name="com.tumblr.videohub.view.VideoHubActivity" android:theme="@style/Theme.Tumblr.VideoHub"/>
<activity android:exported="false" android:label="@string/community_label_settings_title_2" android:name="com.tumblr.communitylabel.view.settings.user.CommunityLabelSettingsActivity" android:screenOrientation="portrait" android:theme="@style/Theme.Tumblr.SolidActionBar.PushSettings" android:windowSoftInputMode="adjustResize|stateHidden"/>
<activity android:exported="false" android:label="@string/blog_community_label_settings" android:name="com.tumblr.communitylabel.view.settings.blog.BlogCommunityLabelSettingsActivity" android:screenOrientation="portrait" android:theme="@style/Theme.Tumblr.SolidActionBar.PushSettings" android:windowSoftInputMode="adjustResize|stateHidden"/>
<activity android:label="@string/configurable_tabs_toolbar_title" android:launchMode="singleTask" android:name="com.tumblr.configurabletabs.ui.ConfigureDashboardTabsActivity" android:screenOrientation="portrait" android:theme="@style/Theme.Tumblr.NoActionBar"/>
<activity android:name="com.tumblr.badges.badges.supporterbadge.view.SupporterBadgeActivity" android:screenOrientation="portrait" android:theme="@style/Theme.Tumblr.NoActionBar.DarkStatusBar"/>
<activity android:name="com.tumblr.badges.badges.freeclaim.view.FreeBadgeClaimActivity" android:screenOrientation="portrait" android:theme="@style/Theme.Tumblr.NoActionBar.DarkStatusBar"/>
<receiver android:enabled="true" android:exported="true" android:name="com.tumblr.engagement.AppEngagementBroadcastReceiver">
<intent-filter>
<action android:name="com.google.android.engage.action.PUBLISH_RECOMMENDATION"/>
</intent-filter>
</receiver>
<activity android:label="@string/delete_account" android:name="com.tumblr.accountdeletion.DeleteAccountActivity" android:screenOrientation="portrait" android:theme="@style/Theme.Tumblr.SolidActionBar.PushSettings" android:windowSoftInputMode="adjustResize"/>
<activity android:exported="false" android:label="@string/sexually_explicit_content_appeal" android:name="com.tumblr.appeal.view.adultcontent.AdultContentAppealActivity" android:screenOrientation="portrait" android:theme="@style/Theme.Tumblr.SolidActionBar" android:windowSoftInputMode="adjustResize|stateHidden"/>
<activity android:exported="false" android:name="com.tumblr.premium.onboarding.PremiumOnboardingActivity" android:theme="@style/Theme.Tumblr.NoActionBar.DarkStatusBar"/>
<activity android:exported="false" android:name="com.tumblr.premium.perks.PremiumPerksActivity" android:theme="@style/Theme.Tumblr.NoActionBar.DarkStatusBar"/>
<activity android:exported="false" android:name="com.tumblr.premium.payments.PaymentsAndPurchasesActivity" android:theme="@style/Theme.Tumblr.NoActionBar.DarkStatusBar"/>
<activity android:exported="false" android:label="@string/cancel_subscription" android:name="com.tumblr.premium.cancel.PremiumCancelActivity" android:screenOrientation="portrait" android:theme="@style/Theme.Tumblr.NoActionBar.DarkStatusBar"/>
<provider android:authorities="com.tumblr" android:exported="false" android:label="Tumblr" android:name="com.tumblr.content.TumblrProvider" android:syncable="true"/>
<meta-data android:name="com.google.android.gms.version" android:value="@integer/google_play_services_version"/>
<meta-data android:name="com.google.android.gms.ads.APPLICATION_ID" android:value="ca-app-pub-5932904123661942~3080059875"/>
<meta-data android:name="android.max_aspect" android:value="2.1"/>
<meta-data android:name="ignore_ssl_errors" android:value="false"/>
<meta-data android:name="com.facebook.sdk.ApplicationId" android:value="@string/FACEBOOK_APP_ID"/>
<meta-data android:name="com.samsung.android.icon_container.has_icon_container" android:value="true"/>
<meta-data android:name="com.google.android.engage.service.ENV" android:value="PRODUCTION"/>
<activity android:exported="true" android:launchMode="@integer/launch_mode" android:name="com.tumblr.ui.activity.JumpoffActivity" android:theme="@style/Theme.Tumblr.Splash">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
<category android:name="android.intent.category.MULTIWINDOW_LAUNCHER"/>
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.PICK"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="com.facebook.orca.category.PLATFORM_THREAD_20150314"/>
</intent-filter>
<meta-data android:name="android.app.shortcuts" android:resource="@xml/shortcuts"/>
</activity>
<activity android:name="com.tumblr.ui.activity.RootActivity" android:screenOrientation="portrait" android:theme="@style/Theme.Tumblr.Root"/>
<activity android:configChanges="keyboardHidden|orientation|screenSize" android:name="com.tumblr.ui.activity.webview.WebViewActivity" android:screenOrientation="portrait" android:theme="@style/Theme.Tumblr.SolidActionBarNoIcon" android:windowSoftInputMode="adjustResize"/>
<activity android:name="com.tumblr.ui.activity.SimpleTimelineActivity" android:screenOrientation="portrait" android:theme="@style/Theme.Tumblr.SolidActionBarNoIcon"/>
<activity android:name="com.tumblr.ui.activity.BlogHeaderTimelineActivity" android:screenOrientation="portrait" android:theme="@style/Theme.Tumblr.SolidActionBarNoIcon"/>
<activity android:name="com.tumblr.ui.activity.RidiculousCroppingActivity" android:screenOrientation="portrait" android:theme="@style/Theme.Tumblr.RidiculousCrop"/>
<activity android:name="com.tumblr.ui.activity.BlogPagesActivity" android:parentActivityName="com.tumblr.ui.activity.RootActivity" android:screenOrientation="portrait" android:theme="@style/Theme.Tumblr.Blog">
<meta-data android:name="android.support.PARENT_ACTIVITY" android:value=".ui.activity.RootActivity"/>
</activity>
<activity android:label="@string/answertime" android:name="com.tumblr.answertime.AnswertimeActivity" android:screenOrientation="portrait" android:theme="@style/Theme.Tumblr.Answertime"/>
<activity android:name="com.tumblr.ui.activity.GraywaterTakeoverActivity" android:screenOrientation="portrait" android:theme="@style/Theme.Tumblr.NoActionBar.DarkStatusBar"/>
<activity android:exported="true" android:name="com.tumblr.ui.activity.SearchActivity" android:screenOrientation="portrait" android:theme="@style/Theme.AppCompat.Light.NoActionBar">
<intent-filter>
<action android:name="com.google.android.gms.actions.SEARCH_ACTION"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
<activity android:name="com.tumblr.ui.activity.GraywaterBlogSearchActivity" android:screenOrientation="portrait" android:theme="@style/Theme.AppCompat.Light.NoActionBar"/>
<activity android:label="@string/hint_inblog_search" android:name="com.tumblr.ui.widget.blogpages.search.InblogSearchActivity" android:screenOrientation="portrait" android:theme="@style/BlogTagsSearch" android:windowSoftInputMode="adjustResize"/>
<activity android:name="com.tumblr.ui.activity.PostPermalinkTimelineActivity" android:screenOrientation="portrait" android:theme="@style/Theme.Tumblr.NoActionBar"/>
<activity android:label="@string/edit_appearance" android:name="com.tumblr.ui.activity.CustomizeOpticaBlogPagesActivity" android:screenOrientation="portrait" android:theme="@style/Theme.Tumblr" android:windowSoftInputMode="adjustPan|stateHidden"/>
<activity android:label="@string/drafts_title" android:name="com.tumblr.ui.activity.GraywaterDraftsActivity" android:screenOrientation="portrait" android:theme="@style/Theme.Tumblr.NoActionBar.DarkStatusBar"/>
<activity android:label="@string/followers_title" android:name="com.tumblr.ui.activity.FollowerActivity" android:screenOrientation="portrait" android:theme="@style/Theme.Tumblr.Transparent" android:windowSoftInputMode="adjustPan"/>
<activity android:label="@string/blocked_tumblrs_title" android:name="com.tumblr.ui.activity.BlockedTumblrsActivity" android:screenOrientation="portrait" android:theme="@style/Theme.Tumblr.Transparent" android:windowSoftInputMode="adjustPan"/>
<activity android:label="@string/inbox_title" android:name="com.tumblr.ui.activity.GraywaterInboxActivity" android:parentActivityName="com.tumblr.ui.activity.RootActivity" android:screenOrientation="portrait" android:theme="@style/Theme.Tumblr.NoActionBar.DarkStatusBar">
<meta-data android:name="android.support.PARENT_ACTIVITY" android:value=".ui.activity.RootActivity"/>
</activity>
<activity android:label="@string/setting_label_filter" android:name="com.tumblr.ui.activity.FilterSettingsActivity" android:screenOrientation="portrait" android:theme="@style/Theme.Tumblr.SolidActionBar.PushSettings" android:windowSoftInputMode="adjustResize|stateHidden"/>
<activity android:label="@string/setting_media_autoplay" android:name="com.tumblr.ui.activity.MediaAutoplaySettingsActivity" android:screenOrientation="portrait" android:theme="@style/Theme.Tumblr.SolidActionBar.PushSettings"/>
<activity android:label="YKit Settings" android:name="dev.maelstrom.ykit.settings.YkitSettingsActivity" android:screenOrientation="portrait" android:theme="@style/Theme.Tumblr.SolidActionBar.PushSettings"/>
<activity android:label="@string/setting_label_blog_privacy_title" android:name="com.tumblr.ui.activity.BlogPrivacySettingsActivity" android:screenOrientation="portrait" android:theme="@style/Theme.Tumblr.SolidActionBar.PushSettings"/>
<activity android:label="@string/setting_label_theme" android:name="com.tumblr.ui.activity.AppThemeSettingsActivity" android:screenOrientation="portrait" android:theme="@style/Theme.Tumblr.SolidActionBar.PushSettings"/>
<activity android:label="@string/pages" android:name="com.tumblr.ui.activity.blog.BlogPagesSettingsActivity" android:screenOrientation="portrait" android:theme="@style/Theme.Tumblr.Transparent"/>
<activity android:name="com.tumblr.ui.activity.FullScreenCameraActivity" android:resizeableActivity="false" android:screenOrientation="portrait" android:theme="@style/Theme.Tumblr.NoActionBar" android:windowSoftInputMode="adjustResize"/>
<activity android:name="com.tumblr.ui.activity.FullScreenCameraPreviewActivity" android:resizeableActivity="false" android:screenOrientation="portrait" android:theme="@style/Theme.Tumblr.NoActionBar" android:windowSoftInputMode="adjustResize"/>
<activity android:name="com.tumblr.ui.activity.FullScreenEditorActivity" android:resizeableActivity="false" android:screenOrientation="portrait" android:theme="@style/Theme.Tumblr.NoActionBar" android:windowSoftInputMode="adjustResize"/>
<activity android:configChanges="keyboardHidden|orientation|screenLayout|screenSize|smallestScreenSize" android:hardwareAccelerated="true" android:name="com.tumblr.ui.activity.FullScreenYouTubePlayerActivity" android:theme="@style/Theme.Tumblr.NoActionBar"/>
<activity android:label="@string/queue_title" android:name="com.tumblr.ui.activity.GraywaterQueuedActivity" android:screenOrientation="portrait" android:theme="@style/Theme.Tumblr.NoActionBar.DarkStatusBar"/>
<activity android:exported="true" android:label="@string/settings" android:name="com.tumblr.settings.SettingsActivity" android:screenOrientation="portrait" android:theme="@style/Theme.Tumblr.SolidActionBar.PushSettings">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.NOTIFICATION_PREFERENCES"/>
</intent-filter>
</activity>
<activity android:label="@string/settings" android:name="com.tumblr.settings.SettingPossibleValuesActivity" android:screenOrientation="portrait" android:theme="@style/Theme.Tumblr.SolidActionBar.PushSettings"/>
<activity android:label="@string/settings" android:name="com.tumblr.settings.accountsettings.AccountSettingsActivity" android:screenOrientation="portrait" android:theme="@style/Theme.Tumblr.SolidActionBar.PushSettings"/>
<activity android:name="com.tumblr.rating.RatingMoodActivity" android:theme="@style/Theme.Tumblr.NoActionBar.Rating"/>
<activity android:name="com.tumblr.rating.RatingPromptActivity" android:theme="@style/Theme.Tumblr.NoActionBar.Rating"/>
<activity android:name="com.tumblr.posts.postform.CanvasActivity" android:parentActivityName="com.tumblr.ui.activity.RootActivity" android:screenOrientation="portrait" android:theme="@style/CanvasTheme" android:windowSoftInputMode="adjustResize|stateHidden"/>
<activity android:name="com.tumblr.posts.tagsearch.TagSearchActivity" android:screenOrientation="portrait" android:theme="@style/TagSearchTheme" android:windowSoftInputMode="adjustResize|stateHidden"/>
<activity android:configChanges="orientation|screenSize" android:name="com.tumblr.ui.activity.GalleryActivity" android:parentActivityName="com.tumblr.ui.activity.RootActivity" android:screenOrientation="portrait" android:theme="@style/Theme.Tumblr.NoActionBar.Gallery"/>
<activity android:name="com.tumblr.ui.activity.GalleryPreviewActivity" android:screenOrientation="fullUser" android:theme="@style/Theme.Tumblr.NoActionBar"/>
<activity android:name="com.tumblr.ui.activity.AudioPostSearchActivity" android:parentActivityName="com.tumblr.ui.activity.RootActivity" android:screenOrientation="portrait" android:theme="@style/AudioPostSearch" android:windowSoftInputMode="adjustResize"/>
<activity android:hardwareAccelerated="false" android:label="@string/tumblr_app_name" android:name="com.tumblr.ui.fragment.dialog.AvatarChooseAndCropActivity" android:screenOrientation="portrait" android:theme="@style/Theme.Tumblr.NoActionBar"/>
<activity android:name="com.tumblr.settings.account.BlogNameChangeActivity" android:screenOrientation="portrait" android:theme="@style/Theme.Tumblr.NoActionBar.Onboarding.NameChange" android:windowSoftInputMode="adjustResize"/>
<activity android:name="com.tumblr.activity.rollup.ActivityNotificationRollupDetailActivity" android:screenOrientation="portrait" android:theme="@style/Theme.Tumblr.SimpleActivityNoIcon" android:windowSoftInputMode="stateUnchanged"/>
<activity android:name="com.tumblr.ui.activity.PhotoLightboxActivity" android:screenOrientation="fullUser" android:theme="@style/Theme.Tumblr.Lightbox"/>
<activity android:exported="true" android:label="@string/message_a_tumblr" android:name="com.tumblr.messenger.ChooseParticipantsActivity" android:screenOrientation="portrait" android:theme="@style/ChooseParticipants">
<intent-filter>
<action android:name="android.intent.action.SEND"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:mimeType="text/plain"/>
<data android:mimeType="image/*"/>
</intent-filter>
<meta-data android:name="android.service.chooser.chooser_target_service" android:value="androidx.sharetarget.ChooserTargetServiceCompat"/>
</activity>
<activity android:label="@string/label_conversation" android:launchMode="singleTask" android:name="com.tumblr.messenger.ConversationActivity" android:screenOrientation="portrait" android:theme="@style/Theme.AppCompat.Light.NoActionBar"/>
<activity android:name="com.tumblr.ui.activity.OauthAuthorizeActivity" android:noHistory="true" android:screenOrientation="portrait" android:theme="@style/Theme.Tumblr.NoActionBar"/>
<activity android:exported="true" android:launchMode="singleTask" android:name="com.tumblr.ui.activity.WebsiteInterceptActivity" android:noHistory="true" android:theme="@style/Theme.Tumblr.Splash">
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
<data android:scheme="http"/>
<data android:scheme="https"/>
<data android:host="tumblr.com"/>
<data android:host="www.tumblr.com"/>
<data android:pathPrefix="/download/android"/>
<data android:pathPrefix="/follow/"/>
<data android:pathPrefix="/oauth/authorize"/>
<data android:pathPrefix="/message/"/>
<data android:pathPrefix="/explore/answertime"/>
<data android:pathPrefix="/explore"/>
<data android:pathPrefix="/apps"/>
<data android:pathPrefix="/likes"/>
<data android:pathPrefix="/share/post"/>
<data android:pathPrefix="/dashboard/tab"/>
<data android:pathPrefix="/new"/>
<data android:pathPrefix="/new/audio"/>
<data android:pathPrefix="/new/chat"/>
<data android:pathPrefix="/new/link"/>
<data android:pathPrefix="/new/photo"/>
<data android:pathPrefix="/new/quote"/>
<data android:pathPrefix="/new/text"/>
<data android:pathPrefix="/new/video"/>
<data android:pathPrefix="/premium/success"/>
<data android:pathPrefix="/blaze"/>
</intent-filter>
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
<data android:scheme="http"/>
<data android:scheme="https"/>
<data android:host="tumblr.com"/>
<data android:host="www.tumblr.com"/>
<data android:pathPrefix="/authenticate"/>
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
<data android:scheme="tumblr-auth"/>
<data android:host="x-callback-url"/>
<data android:pathPrefix="/oauth/authorize"/>
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
<data android:host="x-callback-url" android:pathPrefix="/adfreebrowsingonboarding" android:scheme="tumblr"/>
</intent-filter>
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
<data android:host="*.tumblr.com" android:scheme="http"/>
<data android:host="*.tumblr.com" android:scheme="https"/>
</intent-filter>
</activity>
<activity android:exported="true" android:name="com.tumblr.ui.appwidget.ChoosePostWidgetConfigure" android:theme="@style/AppWidgetConfigureDialog">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_CONFIGURE"/>
</intent-filter>
</activity>
<activity android:excludeFromRecents="true" android:exported="true" android:label="@string/post_to_tumblr" android:name="com.tumblr.creation.receiver.ShareActivity" android:noHistory="true">
<intent-filter>
<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="video/*"/>
<data android:mimeType="image/*"/>
</intent-filter>
</activity>
<activity android:name="com.tumblr.ui.activity.GifSearchActivity" android:screenOrientation="portrait" android:theme="@style/GifSearchResults" android:windowSoftInputMode="stateAlwaysHidden|adjustResize"/>
<activity android:launchMode="singleTask" android:name="com.tumblr.settings.account.SingleLineFormActivity" android:screenOrientation="portrait" android:theme="@style/Theme.Tumblr.NoActionBar" android:windowSoftInputMode="adjustResize"/>
<activity android:label="@string/title_blog_settings" android:name="com.tumblr.ui.activity.BlogSettingsActivity" android:screenOrientation="portrait" android:theme="@style/Theme.Tumblr.Transparent" android:windowSoftInputMode="adjustPan"/>
<activity android:label="@string/create_new_tumblr" android:name="com.tumblr.ui.widget.blogpages.CreateBlogActivity" android:screenOrientation="portrait" android:theme="@style/Theme.Tumblr.CreateBlog" android:windowSoftInputMode="adjustResize"/>
<activity android:name="com.tumblr.ui.activity.blog.BlogPagesPreviewActivity" android:parentActivityName="com.tumblr.ui.activity.blog.BlogPagesSettingsActivity" android:screenOrientation="portrait" android:theme="@style/Theme.Tumblr.Blog">
<meta-data android:name="android.support.PARENT_ACTIVITY" android:value=".ui.activity.blog.BlogPagesSettingsActivity"/>
</activity>
<activity android:launchMode="singleTop" android:name="com.tumblr.guce.GuceActivity" android:screenOrientation="portrait" android:theme="@style/Theme.AppCompat.Light.NoActionBar"/>
<activity android:launchMode="singleTask" android:name="com.tumblr.guce.GuceSingleInstanceActivity" android:screenOrientation="portrait" android:theme="@style/Theme.AppCompat.Light.NoActionBar"/>
<activity android:label="@string/posts_review_screen_title" android:name="com.tumblr.blog.projectx.PostsReviewActivity" android:parentActivityName="com.tumblr.ui.activity.RootActivity" android:screenOrientation="portrait" android:theme="@style/Theme.Tumblr.NoActionBar.DarkStatusBar">
<meta-data android:name="android.support.PARENT_ACTIVITY" android:value=".ui.activity.RootActivity"/>
</activity>
<activity android:name="com.tumblr.communityhubs.CommunityHubActivity" android:screenOrientation="portrait" android:theme="@style/CommunityHub"/>
<activity android:name="com.tumblr.tagmanagement.TagManagementActivity" android:screenOrientation="portrait" android:theme="@style/CommunityHub"/>
<activity android:name="com.tumblr.components.audioplayer.ReblogPostActionActivity" android:screenOrientation="portrait" android:theme="@style/Theme.Tumblr.NoActionBar"/>
<activity android:name="com.tumblr.ad.rewarded.RewardedAdComposeActivity" android:theme="@style/Theme.Tumblr.NoActionBar.NoBackground"/>
<activity android:name="com.tumblr.settings.account.askpagetitle.AskPageTitleActivity" android:screenOrientation="portrait" android:theme="@style/Theme.Tumblr.NoActionBar" android:windowSoftInputMode="adjustResize"/>
<receiver android:exported="true" android:label="@string/appwidget_choose_post_label" android:name="com.tumblr.ui.appwidget.ChoosePostWidgetProvider">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE"/>
</intent-filter>
<meta-data android:name="android.appwidget.provider" android:resource="@xml/appwidget_choose_post"/>
</receiver>
<receiver android:name="com.tumblr.receiver.HubShareBroadcastReceiver"/>
<service android:name="com.tumblr.blog.customize.CustomizeService"/>
<receiver android:exported="false" android:name="com.tumblr.messenger.network.MessageNotificationReceiver" android:permission="com.tumblr.permissions.RECEIVER">
<intent-filter android:priority="0">
<action android:name="com.tumblr.ACTION_CHECK_MESSAGES"/>
</intent-filter>
</receiver>
<receiver android:exported="false" android:name="com.tumblr.notes.ConversationalNotificationReceiver" android:permission="com.tumblr.permissions.RECEIVER">
<intent-filter android:priority="0">
<action android:name="com.tumblr.ACTION_NEW_NOTES"/>
</intent-filter>
</receiver>
<receiver android:enabled="true" android:exported="false" android:name="com.tumblr.posts.outgoing.NPSRetryPostReceiver"/>
<receiver android:enabled="true" android:exported="false" android:name="com.tumblr.posts.outgoing.NPSDiscardPostReceiver"/>
<service android:name="com.tumblr.service.notification.BlogUnsubscribeService"/>
<service android:name="com.tumblr.fcm.FCMTokenRegistrarJobService" android:permission="android.permission.BIND_JOB_SERVICE"/>
<service android:exported="true" android:name="com.tumblr.fcm.TumblrFirebaseMessagingService">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT"/>
</intent-filter>
</service>
<provider android:authorities="com.tumblr.fileprovider" android:exported="false" android:grantUriPermissions="true" android:name="androidx.core.content.FileProvider">
<meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/filepaths"/>
</provider>
<receiver android:enabled="true" android:exported="false" android:name="com.tumblr.service.notification.UserNotificationActionEnqueuingReceiver"/>
<receiver android:exported="false" android:name="com.tumblr.receiver.SelectedAppReceiver"/>
<activity android:label="Meadow Sample Feature" android:name="com.tumblr.meadow.ui.FollowersAndConversationsActivity" android:theme="@style/Theme.Tumblr.SolidActionBar"/>
<activity android:label="JC Navigation Sample Feature" android:name="com.tumblr.meadow.ui.election.ElectionEntryPointActivity" android:theme="@style/Theme.Tumblr.NoActionBar"/>
<activity android:label="JC Navigation Sample Feature" android:name="com.tumblr.meadow.ui.NewCampaignEntryPointActivity" android:theme="@style/Theme.Tumblr.NoActionBar"/>
<activity android:label="@string/account_settings_security_v3" android:name="com.tumblr.security.view.ui.securitysettings.SecurityActivity" android:screenOrientation="portrait" android:theme="@style/Theme.Tumblr.NoActionBar" android:windowSoftInputMode="stateHidden"/>
<activity android:label="@string/account_settings_backup_codes_v3" android:name="com.tumblr.security.view.ui.generatecodes.GenerateBackupCodesActivity" android:screenOrientation="portrait" android:theme="@style/Theme.Tumblr.NoActionBar" android:windowSoftInputMode="stateHidden"/>
<activity android:label="@string/account_settings_security_confirmation_2fa_v3" android:name="com.tumblr.security.view.ui.confirmation.TwoFactorAuthEnrolmentActivity" android:screenOrientation="portrait" android:theme="@style/Theme.Tumblr.NoActionBar" android:windowSoftInputMode="stateHidden"/>
<activity android:label="@string/title_activity_labs" android:name="com.tumblr.labs.ui.LabsActivity" android:screenOrientation="portrait" android:windowSoftInputMode="adjustResize"/>
<receiver android:exported="true" android:name="com.tumblr.notificationchannel.ChannelStateChangedReceiver">
<intent-filter>
<action android:name="android.app.action.NOTIFICATION_CHANNEL_BLOCK_STATE_CHANGED"/>
<action android:name="android.app.action.NOTIFICATION_CHANNEL_GROUP_BLOCK_STATE_CHANGED"/>
<action android:name="android.app.action.APP_BLOCK_STATE_CHANGED"/>
</intent-filter>
</receiver>
<provider android:authorities="com.tumblr.KanvasFileProvider" android:exported="false" android:grantUriPermissions="true" android:name="com.tumblr.kanvas.FileProvider">
<meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/kanvas_paths"/>
</provider>
<activity android:name="com.yalantis.ucrop.UCropActivity" android:screenOrientation="portrait" android:theme="@style/Theme.AppCompat.Light.NoActionBar"/>
<service android:enabled="true" android:exported="false" android:foregroundServiceType="mediaPlayback" android:name="com.tumblr.components.audioplayer.TumblrAudioPlayerService" android:stopWithTask="true"/>
<activity android:configChanges="orientation|screenLayout|screenSize|smallestScreenSize" android:name="com.smartadserver.android.library.ui.SASInterstitialActivity" android:theme="@style/SASInterstitialActivityTheme"/>
<provider android:authorities="com.tumblr.smartadserver.transparencyreport" android:exported="false" android:grantUriPermissions="true" android:name="com.smartadserver.android.library.components.transparencyreport.SASTransparencyReport$FileProvider">
<meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/filepaths_smartadserver"/>
</provider>
<activity android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|screenSize|smallestScreenSize|uiMode" android:exported="false" android:name="com.google.android.gms.ads.AdActivity" android:theme="@android:style/Theme.Translucent"/>
<provider android:authorities="com.tumblr.mobileadsinitprovider" android:exported="false" android:initOrder="100" android:name="com.google.android.gms.ads.MobileAdsInitProvider"/>
<service android:enabled="true" android:exported="false" android:name="com.google.android.gms.ads.AdService"/>
<activity android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|screenSize|smallestScreenSize|uiMode" android:exported="false" android:name="com.google.android.gms.ads.OutOfContextTestingActivity"/>
<activity android:excludeFromRecents="true" android:exported="false" android:launchMode="singleTask" android:name="com.google.android.gms.ads.NotificationHandlerActivity" android:taskAffinity="" android:theme="@android:style/Theme.Translucent.NoTitleBar"/>
<property android:name="android.adservices.AD_SERVICES_CONFIG" android:resource="@xml/gma_ad_services_config"/>
<service android:directBootAware="false" android:enabled="@bool/enable_system_alarm_service_default" android:exported="false" android:name="androidx.work.impl.background.systemalarm.SystemAlarmService"/>
<service android:directBootAware="false" android:enabled="@bool/enable_system_job_service_default" android:exported="true" android:name="androidx.work.impl.background.systemjob.SystemJobService" android:permission="android.permission.BIND_JOB_SERVICE"/>
<service android:directBootAware="false" android:enabled="@bool/enable_system_foreground_service_default" android:exported="false" android:name="androidx.work.impl.foreground.SystemForegroundService"/>
<receiver android:directBootAware="false" android:enabled="true" android:exported="false" android:name="androidx.work.impl.utils.ForceStopRunnable$BroadcastReceiver"/>
<receiver android:directBootAware="false" android:enabled="false" android:exported="false" android:name="androidx.work.impl.background.systemalarm.ConstraintProxy$BatteryChargingProxy">
<intent-filter>
<action android:name="android.intent.action.ACTION_POWER_CONNECTED"/>
<action android:name="android.intent.action.ACTION_POWER_DISCONNECTED"/>
</intent-filter>
</receiver>
<receiver android:directBootAware="false" android:enabled="false" android:exported="false" android:name="androidx.work.impl.background.systemalarm.ConstraintProxy$BatteryNotLowProxy">
<intent-filter>
<action android:name="android.intent.action.BATTERY_OKAY"/>
<action android:name="android.intent.action.BATTERY_LOW"/>
</intent-filter>
</receiver>
<receiver android:directBootAware="false" android:enabled="false" android:exported="false" android:name="androidx.work.impl.background.systemalarm.ConstraintProxy$StorageNotLowProxy">
<intent-filter>
<action android:name="android.intent.action.DEVICE_STORAGE_LOW"/>
<action android:name="android.intent.action.DEVICE_STORAGE_OK"/>
</intent-filter>
</receiver>
<receiver android:directBootAware="false" android:enabled="false" android:exported="false" android:name="androidx.work.impl.background.systemalarm.ConstraintProxy$NetworkStateProxy">
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE"/>
</intent-filter>
</receiver>
<receiver android:directBootAware="false" android:enabled="false" android:exported="false" android:name="androidx.work.impl.background.systemalarm.RescheduleReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
<action android:name="android.intent.action.TIME_SET"/>
<action android:name="android.intent.action.TIMEZONE_CHANGED"/>
</intent-filter>
</receiver>
<receiver android:directBootAware="false" android:enabled="@bool/enable_system_alarm_service_default" android:exported="false" android:name="androidx.work.impl.background.systemalarm.ConstraintProxyUpdateReceiver">
<intent-filter>
<action android:name="androidx.work.impl.background.systemalarm.UpdateProxies"/>
</intent-filter>
</receiver>
<receiver android:directBootAware="false" android:enabled="true" android:exported="true" android:name="androidx.work.impl.diagnostics.DiagnosticsReceiver" android:permission="android.permission.DUMP">
<intent-filter>
<action android:name="androidx.work.diagnostics.REQUEST_DIAGNOSTICS"/>
</intent-filter>
</receiver>
<activity android:excludeFromRecents="true" android:exported="false" android:name="com.google.android.gms.auth.api.signin.internal.SignInHubActivity" android:theme="@android:style/Theme.Translucent.NoTitleBar"/>
<service android:exported="true" android:name="com.google.android.gms.auth.api.signin.RevocationBoundService" android:permission="com.google.android.gms.auth.api.signin.permission.REVOCATION_NOTIFICATION" android:visibleToInstantApps="true"/>
<receiver android:exported="true" android:name="com.google.firebase.iid.FirebaseInstanceIdReceiver" android:permission="com.google.android.c2dm.permission.SEND">
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE"/>
</intent-filter>
<meta-data android:name="com.google.android.gms.cloudmessaging.FINISHED_AFTER_HANDLED" android:value="true"/>
</receiver>
<service android:directBootAware="true" android:exported="false" android:name="com.google.firebase.messaging.FirebaseMessagingService">
<intent-filter android:priority="-500">
<action android:name="com.google.firebase.MESSAGING_EVENT"/>
</intent-filter>
</service>
<service android:directBootAware="true" android:exported="false" android:name="com.google.firebase.components.ComponentDiscoveryService">
<meta-data android:name="com.google.firebase.components:com.google.firebase.messaging.FirebaseMessagingKtxRegistrar" android:value="com.google.firebase.components.ComponentRegistrar"/>
<meta-data android:name="com.google.firebase.components:com.google.firebase.messaging.FirebaseMessagingRegistrar" android:value="com.google.firebase.components.ComponentRegistrar"/>
<meta-data android:name="com.google.firebase.components:com.google.firebase.crashlytics.ndk.CrashlyticsNdkRegistrar" android:value="com.google.firebase.components.ComponentRegistrar"/>
<meta-data android:name="com.google.firebase.components:com.google.firebase.crashlytics.FirebaseCrashlyticsKtxRegistrar" android:value="com.google.firebase.components.ComponentRegistrar"/>
<meta-data android:name="com.google.firebase.components:com.google.firebase.crashlytics.CrashlyticsRegistrar" android:value="com.google.firebase.components.ComponentRegistrar"/>
<meta-data android:name="com.google.firebase.components:com.google.firebase.sessions.FirebaseSessionsRegistrar" android:value="com.google.firebase.components.ComponentRegistrar"/>
<meta-data android:name="com.google.firebase.components:com.google.firebase.installations.FirebaseInstallationsKtxRegistrar" android:value="com.google.firebase.components.ComponentRegistrar"/>
<meta-data android:name="com.google.firebase.components:com.google.firebase.installations.FirebaseInstallationsRegistrar" android:value="com.google.firebase.components.ComponentRegistrar"/>
<meta-data android:name="com.google.firebase.components:com.google.firebase.ktx.FirebaseCommonLegacyRegistrar" android:value="com.google.firebase.components.ComponentRegistrar"/>
<meta-data android:name="com.google.firebase.components:com.google.firebase.FirebaseCommonKtxRegistrar" android:value="com.google.firebase.components.ComponentRegistrar"/>
<meta-data android:name="com.google.firebase.components:com.google.firebase.datatransport.TransportRegistrar" android:value="com.google.firebase.components.ComponentRegistrar"/>
</service>
<activity android:exported="false" android:name="com.google.android.gms.common.api.GoogleApiActivity" android:theme="@android:style/Theme.Translucent.NoTitleBar"/>
<activity android:configChanges="keyboardHidden|orientation|screenSize" android:hardwareAccelerated="true" android:name="com.brandio.ads.DioActivity"/>
<activity android:name="com.brandio.ads.device.PermissionsHandler"/>
<activity android:name="com.brandio.ads.UnityActivity"/>
<activity android:configChanges="keyboardHidden|orientation|screenSize" android:name="com.brandio.ads.DioTranslucentActivity" android:theme="@android:style/Theme.NoTitleBar"/>
<service android:exported="true" android:name="androidx.sharetarget.ChooserTargetServiceCompat" android:permission="android.permission.BIND_CHOOSER_TARGET_SERVICE">
<intent-filter>
<action android:name="android.service.chooser.ChooserTargetService"/>
</intent-filter>
</service>
<service android:enabled="true" android:exported="false" android:name="com.google.firebase.sessions.SessionLifecycleService"/>
<provider android:authorities="com.tumblr.firebaseinitprovider" android:directBootAware="true" android:exported="false" android:initOrder="100" android:name="com.google.firebase.provider.FirebaseInitProvider"/>
<uses-library android:name="androidx.window.extensions" android:required="false"/>
<uses-library android:name="androidx.window.sidecar" android:required="false"/>
<uses-library android:name="android.ext.adservices" android:required="false"/>
<activity android:configChanges="keyboardHidden|orientation|screenLayout|screenSize|smallestScreenSize" android:exported="false" android:name="com.facebook.ads.AudienceNetworkActivity" android:theme="@android:style/Theme.Translucent.NoTitleBar"/>
<provider android:authorities="com.tumblr.AudienceNetworkContentProvider" android:exported="false" android:name="com.facebook.ads.AudienceNetworkContentProvider"/>
<provider android:authorities="com.tumblr.plumber-installer" android:enabled="@bool/leak_canary_plumber_auto_install" android:exported="false" android:name="leakcanary.internal.PlumberInstaller"/>
<service android:directBootAware="true" android:exported="false" android:name="androidx.room.MultiInstanceInvalidationService"/>
<service android:exported="false" android:name="com.google.android.datatransport.runtime.backends.TransportBackendDiscovery">
<meta-data android:name="backend:com.google.android.datatransport.cct.CctBackendFactory" android:value="cct"/>
</service>
<receiver android:directBootAware="false" android:enabled="true" android:exported="true" android:name="androidx.profileinstaller.ProfileInstallReceiver" android:permission="android.permission.DUMP">
<intent-filter>
<action android:name="androidx.profileinstaller.action.INSTALL_PROFILE"/>
</intent-filter>
<intent-filter>
<action android:name="androidx.profileinstaller.action.SKIP_FILE"/>
</intent-filter>
<intent-filter>
<action android:name="androidx.profileinstaller.action.SAVE_PROFILE"/>
</intent-filter>
<intent-filter>
<action android:name="androidx.profileinstaller.action.BENCHMARK_OPERATION"/>
</intent-filter>
</receiver>
<service android:exported="false" android:name="com.google.android.datatransport.runtime.scheduling.jobscheduling.JobInfoSchedulerService" android:permission="android.permission.BIND_JOB_SERVICE"/>
<receiver android:exported="false" android:name="com.google.android.datatransport.runtime.scheduling.jobscheduling.AlarmManagerSchedulerBroadcastReceiver"/>
<activity android:configChanges="orientation|screenSize" android:exported="true" android:name="com.amazon.aps.ads.activity.ApsInterstitialActivity" android:theme="@style/NoWindow"/>
<activity android:configChanges="orientation|screenSize" android:exported="true" android:name="com.amazon.device.ads.DTBInterstitialActivity"/>
<meta-data android:name="com.google.android.play.billingclient.version" android:value="5.2.1"/>
<activity android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|screenSize" android:exported="false" android:name="com.android.billingclient.api.ProxyBillingActivity" android:theme="@android:style/Theme.Translucent.NoTitleBar"/>
<meta-data android:name="com.facebook.soloader.enabled" android:value="false"/>
<activity android:exported="false" android:name="com.google.android.play.core.common.PlayCoreDialogWrapperActivity" android:stateNotNeeded="true" android:theme="@style/Theme.PlayCore.Transparent"/>
<meta-data android:name="com.android.dynamic.apk.fused.modules" android:value="base"/>
<meta-data android:name="com.android.stamp.source" android:value="https://play.google.com/store"/>
<meta-data android:name="com.android.stamp.type" android:value="STAMP_TYPE_STANDALONE_APK"/>
<meta-data android:name="com.android.vending.splits" android:resource="@xml/splits0"/>
<meta-data android:name="com.android.vending.derived.apk.id" android:value="2"/>
</application>
</manifest>