1. Declared Android permissions
| Permission | Purpose in WiFi Stream | User-visible effect |
|---|---|---|
INTERNET |
Opens local HTTP/WebSocket sockets and allows Google Mobile Ads/UMP internet requests. | Joiners receive local media; ads and privacy messages may load from Google. |
ACCESS_NETWORK_STATE |
Checks whether a suitable Wi-Fi/Ethernet/local interface is available. | The Home screen can display connection readiness. |
ACCESS_WIFI_STATE |
Supports Wi-Fi awareness needed for the same-network feature. | No password or Wi-Fi configuration change is requested. |
CHANGE_WIFI_MULTICAST_STATE |
Acquires a multicast lock while discovering Android NSD/mDNS Host services. | Nearby Hosts can appear automatically; may use additional battery while searching. |
FOREGROUND_SERVICE |
Keeps a user-started Host session’s local servers alive while Android manages background work. | An ongoing “Active streaming” service runs only while hosting. |
FOREGROUND_SERVICE_MEDIA_PLAYBACK |
Declares Watch together as user-started media playback/streaming on recent Android versions. | The synchronized Host can keep its explicit playback session active and visible. |
FOREGROUND_SERVICE_CONNECTED_DEVICE |
Declares Share files as a user-started continuous network transfer to connected Joiner devices. | The Host can keep the selected LAN library reachable without playing a video locally. This normal permission does not grant broad file or nearby-device access. |
POST_NOTIFICATIONS |
Lets Android show the active Host notification on Android 13+. | Watch together names the selected file and provides “Stop Streaming”; Share files shows the number of shared videos and provides “Stop Sharing.” This permission is requested at runtime. |
com.google.android.gms.permission.AD_ID |
Contributed by Google Mobile Ads in the merged release manifest so the SDK can access Android’s resettable advertising identifier where available and allowed. | Used for advertising-related purposes subject to Android settings, consent/ad-serving mode, Google policy, and the Privacy Policy. It is not requested through a runtime dialog. |
READ_BASIC_PHONE_STATE |
Contributed by Google Mobile Ads 1.4.0. Android describes this as non-dangerous basic phone-state access, such as cellular network type and software version. | No runtime prompt. This is not READ_PHONE_STATE and does not grant phone number, call-log, SMS, or precise phone-state access. |
WAKE_LOCK |
Contributed transitively by AndroidX WorkManager. It allows a library to keep the processor awake temporarily while work is running. | No runtime prompt. A wake lock can affect battery use; it does not authorize lock-screen media playback. |
com.vcw.wifistream.DYNAMIC_RECEIVER_NOT_EXPORTED_PERMISSION |
Signature-level internal permission contributed by AndroidX Core to protect non-exported dynamic broadcast receivers. | Not a sensitive-data permission and not grantable to unrelated apps because it is signature protected. |
2. Access to selected videos
WiFi Stream opens Android’s Storage Access Framework document picker with the
video/* filter. The user chooses one document for Watch together or one or more
documents for Share files, and Android grants the app read access only to those document
URIs. The app attempts to retain each URI permission where the document provider supports it.
- No
READ_MEDIA_VIDEO, legacy external-storage, or all-files permission is declared. - The app does not scan the device media library or choose videos without user action.
- Originals stay with their document providers; the app reads ranges to play or stream the requested item.
- Share files sends each Joiner the selected items’ display names, sizes, media types, durations, opaque session IDs, and stream URLs; Android document URIs remain on the Host.
- The app does not intentionally create a permanent Joiner download, although playback components may buffer data temporarily.
3. Local network path
| Component | Observed implementation | Information exposed locally |
|---|---|---|
| Host discovery | Android NSD / DNS-SD service _vcwstream._tcp. with multicast |
Host Android model label, HTTP port, WebSocket port, random session ID, protocol version, and Host LAN address through resolution |
| Video server | HTTP range server, default TCP port 8787; GET/HEAD at legacy /video or the Share files route /video/[opaque item ID], with a random token |
Requested video bytes, media type, byte length/ranges, token in the request URL, and IP connection metadata |
| Session messaging | WebSocket server, default TCP port 8788 |
Device model label, in-memory random Joiner UUID, IP address and session mode; Watch together adds playback position/state/speed and timing samples; Share files adds catalog names, sizes, types, durations, opaque IDs and stream URLs |
| Manual connection | Joiner enters Host address or address with HTTP port; WebSocket defaults to the next port | The entered address is used for the current connection and no address-history store was observed |
| Ads and consent | Google Mobile Ads Next-Gen SDK and UMP | External Google processing described in the Privacy Policy |
4. Cleartext local-traffic warning
usesCleartextTraffic="true". Video travels over HTTP and session, catalog, and synchronization messages over
an unencrypted WebSocket. A token controls the media endpoint but does not provide
confidentiality, peer identity verification, or end-to-end encryption.
For safer use:
- use a private home Wi-Fi network or personal hotspot that you control;
- avoid public, hotel, school, workplace, or guest networks unless the operator explicitly allows and secures peer traffic;
- do not stream confidential, intimate, health, financial, legal, or otherwise sensitive material;
- end hosting when finished and do not share session URLs, IPs, ports, or tokens; and
- treat every connected device as a recipient capable of viewing the media.
5. Foreground service and notification
Hosting starts a user-visible foreground service. Watch together runs with the
mediaPlayback type and shows “Streaming [selected video name]” with Stop
Streaming. Share files runs with the connectedDevice type and shows “Sharing
[count] video(s)” with Stop Sharing while the Host’s own player remains idle. Either
notification opens the app when tapped; stopping closes the local servers and ends access.
On Android 13+, WiFi Stream asks for notification permission when the app starts, before requesting ad privacy information, so system dialogs do not overlap. If permission is denied, Android may reduce where the foreground-service notice is displayed even though the user-started service must follow platform rules.
6. Sensitive access not requested
The reviewed manifest does not declare access to:
- camera or microphone;
- contacts, calendar, call log, phone number, SMS, dangerous
READ_PHONE_STATE, precise phone state, or nearby Bluetooth devices; - precise/coarse/background geographic location;
- broad photos/videos, legacy storage, or all-files management;
- biometrics, health records, activity recognition, or accessibility services; or
- screen capture, overlays, VPN, usage access, or device administration.
7. Android backup and device transfer
The app sets android:allowBackup="true" and no custom data-extraction rules
were observed. When the device user enables Android backup, eligible local app data such
as SharedPreferences can be uploaded to the user’s backup service (commonly Google Drive)
or transferred to a replacement device. This can include local ad-frequency counters and
any SDK preference/consent state stored in a backup-eligible location. It does not back up
the selected original video through WiFi Stream.
Android/Google—not a WiFi Stream publisher server—operates this path. Users can manage backup in Android or Google account settings. The publisher should decide before release whether backup is needed and add explicit exclusions or disable it if preference state should not transfer.
Android’s official Auto Backup documentation explains eligible files and user controls.
8. Manage access
- Notification permission: Android Settings → Apps → WiFi Stream → Notifications.
- Stop active hosting: use End session in the app or Stop Streaming in the notification.
- Clear local records/grants: Android Settings → Apps → WiFi Stream → Storage → Clear storage.
- Remove all app access: uninstall WiFi Stream. This does not delete the original video.
- Manage backed-up preferences: use Android/Google system backup settings; clearing app storage does not necessarily delete an existing cloud backup.
- Advertising choices: use the in-app Privacy choices control when shown and Android’s advertising privacy controls.
Questions: support email pending.