# Spotify Android App — Feature Documentation

## 1. Core Features

Spotify (com.spotify.music) is a music and audio streaming platform. Its primary purpose is on-demand playback of music tracks, podcasts, audiobooks, and live audio content. The app provides personalized recommendations, social listening experiences, curated playlists, and family/managed account controls.

Key differentiators evident from the codebase:

- **Spotify Connect** — remote playback control across a wide range of device types (smartphones, smart speakers, TVs, game consoles, Bluetooth devices, Android Auto, AirPlay, Cast, wired, and more)
- **Jam (Social Connect)** — real-time collaborative listening sessions with `SessionMember` models and live-sharing infrastructure via Ably
- **Managed Family Accounts** — full parental control system for child/young listener accounts including content blocking, PIN protection, and graduation flows
- **SongDNA** — music knowledge graph exploring samples, covers, collaborators, and creative connections (community-sourced via WhoSampled)
- **Scannables (Spotify Codes)** — proprietary QR-like scannable codes for sharing content via camera
- **Offline Playback** — full offline download system (`POST sp://offline/v2/plugin`)
- **Ad-supported tier** — rich ad system including audio ads, video ads, fullscreen ads, and ad feedback mechanisms

---

## 2. Feature Categories

### 2.1 Authentication & Account Management

**Login Options** (from `accessibility_continue_with_*` strings):
- Email/password login
- "Send login link" passwordless login (`action_log_in_without_password = "send login link"`)
- Continue with Google
- Continue with Facebook
- Continue with Apple
- Continue with Phone number
- Continue with NAVER (Korean market)

**Account Types** (from `account_details_account_type_*` strings):
- `account_details_account_type_self_managed = "Self-managed"` — standard independent account
- `account_details_account_type_managed = "Managed account (you control playback)"` — plan manager-controlled child account
- `account_details_account_type_kids = "Spotify Kids (separate app)"` — Spotify Kids integration
- `account_details_account_type_switch_in_progress = "Account switch in progress"` — transitional state

**Account Switching** (multi-user on one device):
- `account_picker_title_text = "Who's listening?"` — profile selector screen
- `account_picker_info_text = "Get personalized recommendations, playlists, and more."` — subtitle
- `account_switching_disclaimer = "While you are signed in, anyone else using this device will be able to access your account."`
- PIN protection for self-managed accounts on shared devices
- `account_switching_young_listener_disclaimer = "On shared devices, young listeners can switch between managed accounts without a PIN. To access self-managed accounts, the plan manager will need to enter their PIN."`
- `account_switching_logged_in_snackbar_message = "You're now logged in as %1$s"`

**Logout Reasons** (from `f16` enum):
- `UNDEFINED`, `ATTEMPTING_AUTOLOGIN`, `NOT_LOGGED_IN`, `USER_INITIATED`, `FORCED_LOGOUT`, `REMOTE_LOGOUT`, `BOOTSTRAP_FAILURE`, `APP_SHUTDOWN`, `ABROAD_SINCE`, `ACCOUNT_SWITCHING`, `ADDING_ACCOUNT_SWITCHING_ACCOUNT`, `USER_GRADUATION`

**Adaptive Authentication** (navigation routes in `mod0`):
- `ADAPTIVEAUTHENTICATION_START`, `ADAPTIVEAUTHENTICATION_ERROR`, `ADAPTIVEAUTHENTICATION_WEBCHALLENGE`
- reCAPTCHA integration (`https://www.recaptcha.net/recaptcha/api3`)
- Age assurance (`https://age-assurance.spotify.com/check/start`)

---

### 2.2 Music & Audio Playback

**Player State Model** (`com/spotify/player/model/PlayerState.java`):
- `is_playing`, `is_paused`, `is_buffering`, `is_system_initiated`
- `context_uri` / `entity_uri` — the currently playing context (album, playlist, etc.)
- `context_url`, `context_metadata`, `context_restrictions`
- `playback_quality` — streaming quality selection
- `playback_speed` — variable speed playback (podcasts/audiobooks)
- `position_as_of_timestamp` — seek position
- `next_tracks` / `prev_tracks` — queue look-ahead and history
- `sleep_timer` — built-in sleep timer
- `options` — player options (shuffle, repeat, etc.)
- `restrictions` / `suppressions` — server-enforced playback restrictions
- `signals` — player signal list
- `ad_break_context` — ad break state
- `audio_stream` — active audio stream info
- `format` — audio format
- `queue_revision` — queue change tracking
- `play_origin` — analytics: where playback was initiated

**Playback Modes:**
- Normal sequential playback
- Shuffle (`accessibility_smartshuffle = "Smart Shuffle"`)
- Smart Shuffle (AI-enhanced shuffle)
- Repeat (track/context)
- Sleep timer

**Content Types** (ComsScore `ContentType` interface):
- `LONG_FORM_ON_DEMAND` (112) — albums, playlists
- `SHORT_FORM_ON_DEMAND` (111) — short clips
- `LIVE` (113) — live streaming
- `USER_GENERATED_LONG_FORM_ON_DEMAND` (122)
- `USER_GENERATED_SHORT_FORM_ON_DEMAND` (121)
- `USER_GENERATED_LIVE` (123)
- `BUMPER` (199) — ad bumpers

**Picture-in-Picture Mode:** `NowPlayingActivity` has explicit PiP support (`isInPictureInPictureMode()`, `PictureInPictureParams`)

**Now Playing View** (`NowPlayingActivity`):
- Orientation-aware layout (`activity_now_playing` / `activity_now_playing_duo` for duo/foldable)
- Shared element transitions with custom exit animation (`nowplaying_activity_exit`)
- Display cutout mode support (Android 9+)

**Video Playback** (API endpoints):
- `POST sp://videoplayer/v1/state`
- `POST sp://videoplayer/v1/advance`
- `POST sp://videoplayer/v1/error`
- Embedded NPV fullscreen video: `ADS_EMBEDDED_NPV_FULLSCREEN_VIDEO`

---

### 2.3 Podcasts & Shows

**API Endpoints:**
- `GET sp://core-show/v1/shows/{showId}` — show details
- `GET sp://core-show/unstable/unfinished/episodes` — resume unfinished episodes
- `GET sp://core-show/unstable/decorate` — show decoration/metadata
- `GET sp://core-collection/unstable/{username}/list/episodes/union` — user's episode collection

**UI Strings:**
- `about_podcast_title = "About the podcast"`
- Episode queue management (add to queue, skip)
- Unfinished episodes tracking

---

### 2.4 Audiobooks

Search entity proto includes `AUDIOBOOK_FIELD_NUMBER = 13` and `AUTHOR_FIELD_NUMBER = 17`, confirming audiobook browsing with author pages. Library item types include `audiobook` and `author` (from `acw.a()` switch).

---

### 2.5 Search

**Search Entity Types** (`com/spotify/searchview/proto/Entity.java`):
- `ARTIST` (4), `TRACK` (5), `ALBUM` (6), `PLAYLIST` (7), `GENRE` (8), `AUDIO_SHOW` (9), `AUDIO_EPISODE` (10), `PROFILE` (11), `AUDIOBOOK` (13), `SECTION` (14), `NEW_RELEASE` (16), `AUTHOR` (17), `RECENT_SEARCH` (18), `CONCERT` (19), `BEST_MATCH` (20), `VENUE` (21), `KALLAX` (22), `PODCAST_CHAPTER` (23)
- Autocomplete (`AUTOCOMPLETE_FIELD_NUMBER = 2046`)
- SERP metadata (`SERP_METADATA_FIELD_NUMBER = 2047`)
- Search query navigation parameter: `search_query`
- Recent searches stored and displayed

**Search Scopes:**
- `add_blocked_content_search_placeholder = "Search"` — content blocking search for parental controls
- `add_to_playlist_find_playlist_hint = "Find playlist"` — in-context playlist search
- Search session ID tracking (`SEARCH_SESSION_ID`)

---

### 2.6 Your Library

**Library Item Types** (from `acw.a()` switch in library context):
- `album`, `artist`, `audiobook`, `author`
- `playlist`, `playlist_folder`
- `podcast`, `course`
- `liked_songs`, `your_episodes`, `new_episodes`
- `local_files`, `cached_files`, `import_music`
- `event`, `events_hub_navigation`, `concert_campaign`
- `venue`
- `prerelease`
- `add_artist`, `add_podcast`

**Library Tags** (`YourLibraryTagsResponse` proto) — tag/filter system for library organization with `classGroup` groupings

**Playlist Management:**
- `add_to_playlist_new_playlist_button_text = "New playlist"`
- `add_to_playlist_refine_details_title = "Refine details"`
- Folder support: `add_to_playlist_empty_view_folder_title = "This folder is empty"`
- `add_to_playlist_save_in_section_header = "Save in"`
- `add_to_playlist_saved_in_section_header = "Saved in"`

---

### 2.7 Social Features — Jam (Live Sharing)

**Jam / Social Connect** (`com.spotify.jam.internal.socialconnect.models.SessionMember`):
- Real-time collaborative listening session with multiple members
- Navigation routes: `live_sharing_session_dismissed`, `live_sharing_dialog`
- Logo hosted at `https://misc.spotifycdn.com/livesharing/meet_logo_large.png`
- Live session state tracking

**Activity Feed:**
- `activity_feed_nav_title = "Activity"` — dedicated activity feed tab
- `activity_indicator_current_content_description = "Currently playing %1$s by %2$s."`
- `activity_indicator_last_played_content_description = "Played %1$s by %2$s %3$s."`
- `activity_button_custom_accessibility_action = "open listening activity details"`

**Blend:**
- `accessibility_title = "Blend Taste Match"` — Blend playlist taste matching feature

**Reactions:**
- `action_react_content_description = "Double tap and hold to react"`
- Emoji reaction system with full emoji category support (emotions, people, animals, food, travel, activity, objects, symbols, flags)

**Sharing:**
- `action_share = "Share via"` / `action_copy = "Copy link"`
- `share_id`, `share_url`, `full_url`, `share_format_id` SharedPreferences keys
- TikTok/Douyin integration (Aweme SDK: `_aweme_open_sdk_params_*` keys)
- WhatsApp Status: `https://wa.me/status`
- Branch.io deep link sharing: `https://spotify.link/content_linking?~campaign=`
- Content linking campaigns

---

### 2.8 Spotify Connect & Device Management

**Supported Device Types** (from `acw.c()` switch):
- `airplay_speaker`, `audio_dongle`, `automobile`, `avr`
- `bluetooth_headphones`, `bluetooth_car`, `bluetooth_speaker`, `bluetooth_unknown`
- `cast_audio`, `cast_video`, `chromebook`, `computer`
- `game_console`, `home_thing` (Spotify smart speaker)
- `smartphone`, `smartwatch`, `face_wearable`, `speaker`
- `stb` (set-top box), `tablet`, `tv`
- `unknown_spotify`

**Connection Protocols** (from `acw.d()` switch):
- `airplay`, `android_auto`, `bluetooth`, `cast`, `connect`, `self`, `wired`

**Device UX:**
- `accessibility_device_row_disabled = "The %s device is disabled."`
- `accessibility_label_volume_for_device = "Volume for %s"`
- `accessibility_open_bluetooth_settings = "Open bluetooth devices in system settings"`
- `accessibility_open_context_menu_for_device = "Open context menu for %s"`
- Device discovery dialogs: `DISCOVERED_DEVICE`, `TAKE_OVER_DIALOG` (from `e9b0` function)

**Android Wear / WearOS** (from `android_wear_capabilities` array):
- `auto_login_request`, `user_info_request`, `play_uri_request`
- `pull_playback_request`, `seek_to_request`, `add_to_queue_request`, `send_signal_request`

**Android Auto / Google Automotive:**
- `androidx.car.app` integration (498 imports)
- Car audio recording (`CarAudioRecord`) for in-car voice input
- `hosts_allowlist` contains Google Automotive package hashes (`com.google.android.projection.gearhead`)
- Android Auto connection protocol listed in `acw.d()`

**Google Cast:**
- `cast_expanded_controller_default_control_buttons` array with closed captions, skip prev/next, mute toggle

---

### 2.9 Offline Playback

- `POST sp://offline/v2/plugin` — registers/configures offline plugin
- Navigation route `local_device` — local device playback state
- Library items include `cached_files` and `local_files`
- `import_music` — local file import to library

---

### 2.10 Scannables (Spotify Codes)

**`ScannablesActivity`** — full QR-code-style scanning experience:
- Camera-based live scanning (`android.hardware.camera2` — 158 imports)
- Photo library import (`scannable_select_from_photos` button)
- Camera permission check before launching scanner
- `ScannablesOnboardingActivity` — first-time onboarding flow
- Social listening mode variant (hides photo button, shows privacy notice, changes hint text: `scannables_social_listening_viewfinder_hint`)
- Haptic feedback (100ms vibration) on successful scan
- Progress dialog during decode/server contact phases
- Result returned via `com.spotify.scannables.scannables.RESULT` extra

---

### 2.11 SongDNA

- `about_songdna_title = "About SongDNA"`
- `about_songdna_body` — explores samples, covers, collaborators, related songs; community-sourced from WhoSampled (now part of Spotify)
- Report errors: `https://artists.spotify.com/c/song-dna-reporting`
- Artist tab schema: `https://ghe.spotify.net/raw/fandango/json-schema/artist-tab-schema/artist-tab.json`

---

### 2.12 Concerts & Events

Search entities include `CONCERT` (19) and `VENUE` (21). Library items include `event`, `events_hub_navigation`, `concert_campaign`, `venue`. Navigation routes include `CONCERTS_*` families in `mod0`. Ticket sale terms: `https://www.spotify.com/legal/ticket-sale-terms/`

---

### 2.13 Advertising System

**Ad Types:**
- Audio ads with breaks (`ad_header_title_music = "Your music will continue after the break"`, `ad_header_title_podcast = "Your podcast will continue after the break"`)
- Sponsored context playlist ads: `ad_header_title_sponsored_context = "Enjoy this playlist with limited ads, after a message from %1$s"`
- App-open ads: `ad_on_app_open_page_context_prompt_text = "Spotify starts after this brief ad"`
- In-feed ads: `ad_feedback_message_infeed = "Thanks. We'll adjust your ad experience."`
- Fullscreen video ads (embedded NPV)
- Carousel ads: `ad_carousel_item_content_description = "Image %1$d of %2$d, %3$s."`
- Standalone mobile overlay ads

**Ad Controls:**
- Skip timer: `ad_delayed_skip_label = "Skip in %d"`
- Fewer ads badge: `ad_break_free_badge_text = "FEWER ADS"`
- Ad feedback (neutral): `ad_feedback_neutral_title = "Tell us more about this ad"`
  - Reasons: "It's not relevant to me", "I'm getting this ad too often", "I think the content was unpleasant", "I think the content was offensive", "I just don't like this ad"
- Ad positive feedback reasons: "It's relevant to me", "I'm interested in this brand", "I'm interested in this product", "The content was enjoyable", "It helped me discover something new"
- Ad preferences URL: `https://www.spotify.com/account/ads/`

**Ad Studio** (full advertiser platform embedded, from `mod0` enum):
- Full campaign creation flow: cold-start campaign → ad set → ad → review and submit
- Duplicate campaigns/ad sets
- Reserved booking campaigns
- Asset library, billing center, business profiles
- Dashboard views for campaigns, ad sets, ads, drafts
- Full-service audio, Quick AI Audio, Quick Audio ad types
- Ad performance reports

**Audience Measurement:** ComScore streaming SDK (`com.comscore.streaming` — 1390 imports, `com.comscore.util` — 114 imports) + ScoreCard Research pixel (`https://sb.scorecardresearch.com/p2`)

---

### 2.14 Parental Controls & Family Plan Management

**Managed Account Flow:**
- `add_blocked_content_empty_title = "Search artists or songs"` — block specific artists/songs for young listeners
- `add_blocked_content_empty_subtitle = "Choose music that this young listener won't be able to play."`
- `add_child_plan_member_title = "Add to your plan"`
- `account_details_remove_member_title = "Remove member"` / `account_details_remove_member_description = "Remove this person's access to your plan."`
- `account_removed_confirmation = "Removed from your plan."`

**Parental Consent (QR Code Flow):**
- `aa_share_parental_consent_title = "Ask your parent or guardian to scan this code"`
- `aa_share_parental_consent_instruction = "They should scan this code with the device where they normally use Spotify."`
- `aa_share_parental_consent_instruction_current_device = "Or, your parent can log in here temporarily. You won't be able to access their account."`
- `aa_share_parental_consent_continue_current_device_button = "Parent login"`
- Parental consent web URL: `https://www.spotify.com/account/parental-consent`

**Young Listener Graduation:**
- `graduation_status` navigation route
- `account_details_account_type_switch_in_progress = "Account switch in progress"` — during graduation
- `account_details_button_disabled = "Account transition is in progress"`
- Support article: `https://support.spotify.com/article/graduating-to-a-self-managed-account/`
- Logout reason `USER_GRADUATION` in `f16` enum

**Explicit Content Control:**
- `account_details_explicit_content_title = "Explicit content"`
- `account_details_explicit_content_description = "Content (labeled with the %s tag) that may contain adult language or themes."`
- Support: `https://support.spotify.com/article/explicit-content/plain/`

**Kids Education Assets:**
- `https://cdn-spotify-gen-alpha.spotifycdn.com/kids-education/RequestParentalConsent.png`
- `https://cdn-spotify-gen-alpha.spotifycdn.com/kids-education/IAM_SeparateAccounts.png`

---

### 2.15 Premium Checkout & Subscription

**Checkout system** (`com.spotify.checkout.proto.model.v1.proto.GetCheckoutPageRequest`, `SubmitCheckoutRequest`):
- In-app purchase flow
- Payment method logos: Visa (`https://wwwcheckout.spotifycdn.com/static/images/play-fop-logos/Visa.png`)
- Recurring premium product image: `https://checkout.spotifycdn.com/static/images/product-images/recurring_premium.png`
- Auto-trial activation: `ACTIVATION_AUTO_TRIAL` route
- Add-on management: `ADD_ON_MANAGEMENT` route

---

### 2.16 Spotify Tap (Hardware Integration)

- Onboarding JSON: `https://spotify-tap.spotifycdn.com/onboarding/generic/Earbuds_Spotify_Tap.json`
- Cadence row navigation (`cadence_row`) — workout/running tempo features

---

### 2.17 Amazon Alexa Integration

Full Alexa skill account linking:
- `https://alexa.amazon.com/spa/skill-account-linking-consent?fragment=skill-account-linking-consent&client_id=amzn1.application-oa2-client.9ef35a57bbb445a9b329037d6fc3643b&scope=alexa::skills:account_linking&skill_stage=live&response_type=code&redirect_uri=`

---

### 2.18 Microsoft Cross-Device SDK

- `com.microsoft.crossdevicesdk` — 119 imports
- Used in `g4v` (Fragment Manager) for cross-device session continuity

---

### 2.19 Content Reporting

- `contentreporting.spotify.com/mobile/content-policy` — in-app content reporting
- Navigation: `report_blocking_data`, `report_blocking_entity_uri` routes
- `actions_picker_report_abuse = "Report"` — report from context menus

---

## 3. User-Facing Capabilities

Users can perform the following actions in the app:

**Playback:**
- Play, pause, skip forward/backward tracks
- Seek within tracks
- Enable/disable shuffle and Smart Shuffle
- Enable repeat (one/all)
- Set sleep timer
- Adjust streaming quality
- Control playback speed (for podcasts/audiobooks)
- Add tracks to queue
- View and reorder queue
- Cast/connect to external devices

**Library & Content:**
- Save albums, artists, playlists, podcasts, audiobooks, songs to library
- Create and manage playlists (including in folders)
- Search for tracks, albums, artists, playlists, podcasts, audiobooks, genres, concerts, venues
- Browse new releases, recommended content
- Import local music files
- Access downloaded content offline

**Social:**
- Start or join a Jam session for collaborative listening
- View friends' listening activity feed
- Create Blends with friends
- Share content via link, copy, or social apps (WhatsApp, TikTok, etc.)
- Scan Spotify Codes with camera
- React to content with emoji reactions

**Account:**
- Switch between multiple accounts on one device
- Manage family plan members (add/remove)
- Block specific content for young listeners
- Set/manage PIN for account switching
- Toggle explicit content filter
- Download personal data (Account Privacy page)
- Upgrade to Premium / manage subscription
- Link Amazon Alexa account

**Content Discovery:**
- Explore SongDNA — samples, covers, collaborators
- Browse concerts and venues
- Rate content with star ratings (`accessiblity_star_rating`)
- Preview tracks (`action_play_content_description = "Preview"`)
- Browse prompted playlists

---

## 4. Settings & Configuration

### Account Details
| Setting | UI Label | Description |
|---|---|---|
| Account type | `"Account type"` | Shows self-managed, managed, or kids type |
| Name | `"Name"` | `"Update name"` on click |
| Profile picture | `"Profile picture"` | Editable profile image |
| Explicit content | `"Explicit content"` | `"Content (labeled with the [E] tag) that may contain adult language or themes."` |

### Streaming
| Setting | UI Label |
|---|---|
| Streaming quality | `accessibility_label_streaming_quality = "Streaming quality %1$s"` |
| Volume | `accessibility_label_volume = "Volume %d"` |
| Mute | SharedPreferences key: `muted` |

### Account Privacy
- `account_privacy_page_header_title = "Account Privacy"`
- `account_privacy_body` — describes data download capability

### Ad Preferences
- Partner preferences: `https://www.spotify.com/account/ads/`

### Bluetooth
- `accessibility_open_bluetooth_settings = "Open bluetooth devices in system settings"`

### Platform Rules
- `https://www.spotify.com/platform-rules/plain`

---

## 5. Background Services

**Session Management:**
- `SessionState` (Parcelable) tracks: `currentUser`, `loggedIn`, `loggingIn`, `loggingOut`, `currentAccountType`, `logoutReason`, `countryCode`, `connected`, `canStream`, `paymentState`, `productType`
- Automatic session restoration and auto-login (`ATTEMPTING_AUTOLOGIN` logout reason)
- Session transfer token: `GET sp://auth/v1/session_transfer_token`
- Remote logout handling (`REMOTE_LOGOUT`)

**Playback Engine:**
- ExoPlayer (`androidx.media3.exoplayer` — 84 imports, `androidx.media3.common` — 135 imports, `androidx.media3.session` — 115 imports) for audio/video decoding
- HLS live stream support: `https://betamax.akamaized.net/cmaf/live/2003445/{eventid}/master.m3u8`
- EMSG/ID3 timed metadata (`https://aomedia.org/emsg/ID3`, `https://developer.apple.com/streaming/emsg-id3`)
- TTML subtitle/caption support (`http://www.w3.org/ns/ttml#parameter`)

**Offline Downloads:**
- WorkManager (`androidx.work.impl` — 83 imports) for background download scheduling
- Offline plugin registration via `POST sp://offline/v2/plugin`

**Real-time Messaging:**
- Ably SDK (`io.ably.lib` — 145 imports) for Jam/live sharing real-time messaging
- Error reference: `https://help.ably.io/error/`

**Analytics & Observability:**
- ComScore streaming measurement running during all audio/video sessions
- ScoreCard Research beacon
- Segment-compatible analytics endpoint: `https://segment-data-us-east.zqtk.net/`
- `ObservabilityPlatformEnabledFromRCProperty` remote config flag
- Firebase (`com.google.firebase` — 47 imports)

**Network Speed Test:**
- Integration with `https://fast.com/` for network speed measurement

**Fraud Prevention:**
- Ravelin SDK (`com.ravelin.core` — 94 imports) for payment fraud detection

**Auth Token Refresh:**
- `GET sp://auth/v1/token_builtin_auth`
- `GET sp://auth/v1/token_web_auth`
- `GET sp://auth/v2/token`

---

## 6. Third-Party Tool & SDK Integrations

| Integration | Package / Endpoint | Purpose |
|---|---|---|
| **ExoPlayer / Media3** | `androidx.media3.*` | Audio and video decoding, HLS, session management |
| **Ably Realtime** | `io.ably.lib` | Jam real-time collaborative sessions |
| **ComScore** | `com.comscore.streaming` | Streaming audience measurement |
| **ScoreCard Research** | `https://sb.scorecardresearch.com/p2` | Audience measurement pixel |
| **Google Firebase** | `com.google.firebase` | Push notifications, analytics, remote config |
| **Google reCAPTCHA** | `https://www.recaptcha.net/recaptcha/api3` | Bot/fraud prevention during auth |
| **Facebook SDK** | `com.facebook` | Facebook login, sharing |
| **Ravelin** | `com.ravelin.core` | Payment fraud detection |
| **Microsoft Cross-Device SDK** | `com.microsoft.crossdevicesdk` | Cross-device session continuity |
| **Jackson** | `com.fasterxml.jackson` | JSON serialization (PlayerState model) |
| **Protocol Buffers** | `com.google.protobuf` | Efficient binary serialization for Esperanto (internal data layer) |
| **MessagePack** | `org.msgpack` | Compact binary serialization |
| **OkHttp** | `okhttp3` | HTTP networking |
| **RxJava 3** | `io.reactivex.rxjava3` | Reactive async programming throughout |
| **Jetpack DataStore** | Detected | Persistent key-value storage replacement for SharedPreferences |
| **Jetpack Compose** | `androidx.compose.ui` | Modern UI components |
| **Cronet (Google Play Services)** | `com.google.android.gms.net.PlayServicesCronetProvider` | High-performance HTTP/QUIC networking |
| **TikTok/Douyin (Aweme SDK)** | `_aweme_open_sdk_params_*` keys | Content sharing to TikTok |
| **Branch.io** | `https://spotify.link/content_linking?~campaign=` | Deep link attribution and sharing |
| **Amazon Alexa** | `alexa.amazon.com` OAuth | Voice assistant account linking |
| **WhoSampled** | Referenced in SongDNA | Sample/cover music knowledge |
| **Kotlinx Serialization** | `kotlinx.serialization` | Kotlin-native JSON/format serialization |
| **getprop (system)** | `p/gr7.java` | Read Android system properties |

**Trusted Account Origins** (from `arrays.xml`):
- `accounts.spotify.com` and regional variants (gew4, gue1, gew1, guc3, gae2)
- `auth-callback.spotify.com`

**Attribution Blocklist** (launchers/installers excluded from install attribution): Samsung, Sony, Xiaomi, OPPO, Vivo, Motorola, Huawei, Transsion, Honor, ZTE, Lenovo, OnePlus, Amazon, LG, Chrome, Google Play

---

## 7. Key Workflows / User Journeys

### 7.1 Authentication Flow
1. **DelegatingLoginActivity** renders a three-dot loading spinner while checking session state
2. On first launch, delegates to **LoginActivity** with `Theme_Glue_NoActionBarWithLogo`
3. If returning from auth callback (`auth-callback.spotify.com`), uses `Theme_Glue_NoActionBar`
4. User selects login method (Google, Facebook, Apple, email, phone, NAVER, passwordless link)
5. Deep link callback (`spotify-auth-music://callback`) returns auth token
6. Session state transitions through `ATTEMPTING_AUTOLOGIN` → `loggedIn = true`
7. `STATE_AUTH_SESSION_WAS_STARTED` persisted across process death for correct flow resumption

### 7.2 Account Switching
1. User taps profile — `"Who's listening?"` picker shown (`account_picker_title_text`)
2. List shows all signed-in accounts with play indicators
3. Young listener accounts switch without PIN; self-managed accounts require plan manager PIN
4. `"You're now logged in as %1$s"` snackbar confirms switch
5. `"Add account"` option opens account creation/login flow

### 7.3 Spotify Code Scanning
1. `ScannablesActivity` created with optional `EXTRA_SOCIAL_LISTENING` flag
2. Checks camera permission; if not granted, launches `ScannablesOnboardingActivity`
3. On permission granted + previously onboarded: activates camera viewfinder
4. Vibrates (100ms) when code is detected in frame
5. Shows progress dialog: "Decoding…" → "Contacting server…"
6. On success: returns scannable ID result to calling activity
7. User can alternatively select a Spotify Code from photo gallery (request code 4567)
8. Social listening mode hides photo picker and shows privacy notice

### 7.4 Jam (Collaborative Listening)
1. Host starts Jam session via live sharing dialog (`live_sharing_dialog` route)
2. Ably channel established for real-time member synchronization
3. `SessionMember` objects track each participant
4. Members join via shared link
5. `live_sharing_session_dismissed` route handles session end
6. Session state and dismissal tracked in navigation state

### 7.5 Parental Consent / Young Listener Setup
1. Young listener opens app, prompted to get parental consent
2. QR code displayed: `"Ask your parent or guardian to scan this code"`
3. Parent scans with their device → directs to `https://www.spotify.com/account/parental-consent`
4. Alternatively: `"Parent login"` button allows parent to temporarily log in on same device
5. Plan manager adds child: `"Add to your plan"` → `ADD_CHILD_PLAN_MEMBER` route
6. Content blocking: plan manager searches artists/songs to block for young listener
7. Graduation: young listener can request transition to self-managed account

### 7.6 Offline Download
1. User taps download button on playlist, album, podcast, or show
2. `POST sp://offline/v2/plugin` registers content for offline delivery
3. WorkManager schedules background downloads
4. Downloaded content tracked under `cached_files` library section
5. Player transparently switches to local cache when offline

### 7.7 Now Playing / Full-Screen Player
1. Tap mini-player → `NowPlayingActivity` launched with shared element transition
2. Activity postpones enter transition until artwork is loaded
3. Duo/foldable layout detected (`activity_now_playing_duo`) for large-screen devices
4. PiP mode available on Android 12+ (SDK ≥ 31)
5. Orientation changes re-render layout if width changes >10%
6. Custom exit animation (`nowplaying_activity_exit`) on close
7. Display cutout mode enabled for notched screens (Android 9+)

### 7.8 Ad Playback Flow
1. Free tier user triggers ad break between tracks or podcasts
2. App-open ad may show on cold launch: `"Spotify starts after this brief ad"`
3. Audio ad plays with header: `"Your music will continue after the break"`
4. Skip button shows countdown: `"Skip in %d"`
5. User can submit ad feedback (positive or negative) to improve targeting
6. `"FEWER ADS"` badge indicates ad-light sponsored contexts
7. Premium upsell may be presented during or after ad break