Skip to content

Commit 01f8363

Browse files
Bare workflow screen recording module script.
1 parent 07193f7 commit 01f8363

File tree

1 file changed

+191
-0
lines changed

1 file changed

+191
-0
lines changed

scripts/setupScreenRecording.js

Lines changed: 191 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,191 @@
1+
const path = require("path");
2+
const fs = require("fs");
3+
4+
const androidBasePath = path.join(__dirname, "../android/app/src/main");
5+
const javaOrKotlinBasePath = path.join(
6+
androidBasePath,
7+
"java/com/digitalnomad91/codebuilderadmin"
8+
);
9+
10+
const androidManifestPath = path.join(androidBasePath, "AndroidManifest.xml");
11+
const mainActivityPathKotlin = path.join(
12+
javaOrKotlinBasePath,
13+
"MainActivity.kt"
14+
);
15+
const serviceKotlinPath = path.join(
16+
javaOrKotlinBasePath,
17+
"ScreenRecordService.kt"
18+
);
19+
20+
// Clean up potential duplicate in old java directory
21+
const oldJavaServicePath = path.join(
22+
androidBasePath,
23+
"java/com/digitalnomad91/codebuilderadmin/ScreenRecordService.kt"
24+
);
25+
if (fs.existsSync(oldJavaServicePath)) {
26+
fs.unlinkSync(oldJavaServicePath);
27+
console.log("🧹 Removed duplicate service file from java directory");
28+
}
29+
30+
const ensurePermissions = () => {
31+
if (!fs.existsSync(androidManifestPath)) {
32+
console.error("AndroidManifest.xml not found.");
33+
return;
34+
}
35+
36+
let manifestContent = fs.readFileSync(androidManifestPath, "utf8");
37+
const permissions = [
38+
"android.permission.RECORD_AUDIO",
39+
"android.permission.FOREGROUND_SERVICE",
40+
"android.permission.SYSTEM_ALERT_WINDOW",
41+
"android.permission.WRITE_EXTERNAL_STORAGE",
42+
"android.permission.READ_EXTERNAL_STORAGE",
43+
"android.permission.MEDIA_PROJECTION",
44+
];
45+
46+
let modified = false;
47+
permissions.forEach((permission) => {
48+
if (!manifestContent.includes(permission)) {
49+
manifestContent = manifestContent.replace(
50+
"</manifest>",
51+
` <uses-permission android:name="${permission}"/>\n</manifest>`
52+
);
53+
modified = true;
54+
}
55+
});
56+
57+
if (modified) {
58+
fs.writeFileSync(androidManifestPath, manifestContent, "utf8");
59+
console.log("✅ AndroidManifest.xml updated with permissions.");
60+
} else {
61+
console.log("✅ AndroidManifest.xml has necessary permissions.");
62+
}
63+
};
64+
65+
const ensureMainActivityModifications = () => {
66+
if (!fs.existsSync(mainActivityPathKotlin)) {
67+
console.error("❌ MainActivity.kt not found.");
68+
return;
69+
}
70+
71+
let content = fs.readFileSync(mainActivityPathKotlin, "utf8");
72+
const injectionCode = `
73+
private val SCREEN_RECORD_REQUEST_CODE = 1001
74+
private var projectionManager: MediaProjectionManager? = null
75+
76+
override fun onCreate(savedInstanceState: Bundle?) {
77+
super.onCreate(savedInstanceState)
78+
projectionManager = getSystemService(Context.MEDIA_PROJECTION_SERVICE) as MediaProjectionManager
79+
}
80+
81+
fun startScreenRecording() {
82+
val intent = projectionManager?.createScreenCaptureIntent()
83+
startActivityForResult(intent, SCREEN_RECORD_REQUEST_CODE)
84+
}
85+
86+
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
87+
super.onActivityResult(requestCode, resultCode, data)
88+
if (requestCode == SCREEN_RECORD_REQUEST_CODE) {
89+
val serviceIntent = Intent(this, ScreenRecordService::class.java)
90+
serviceIntent.putExtra("RESULT_CODE", resultCode)
91+
serviceIntent.putExtra("DATA", data)
92+
startForegroundService(serviceIntent)
93+
}
94+
}
95+
`;
96+
97+
// Add imports if missing
98+
if (
99+
!content.includes("import android.media.projection.MediaProjectionManager")
100+
) {
101+
content = content.replace(
102+
"import com.facebook.react.ReactActivity",
103+
`import com.facebook.react.ReactActivity
104+
import android.content.Context
105+
import android.content.Intent
106+
import android.media.projection.MediaProjectionManager
107+
import android.os.Bundle`
108+
);
109+
}
110+
111+
if (!content.includes("SCREEN_RECORD_REQUEST_CODE")) {
112+
content = content.replace(
113+
/class MainActivity : ReactActivity\(\) \{/,
114+
`class MainActivity : ReactActivity() {${injectionCode}`
115+
);
116+
fs.writeFileSync(mainActivityPathKotlin, content, "utf8");
117+
console.log("✅ MainActivity.kt updated.");
118+
} else {
119+
console.log("✅ MainActivity already modified.");
120+
}
121+
};
122+
123+
const ensureScreenRecordService = () => {
124+
const serviceDir = path.dirname(serviceKotlinPath);
125+
if (!fs.existsSync(serviceDir)) {
126+
fs.mkdirSync(serviceDir, { recursive: true });
127+
console.log("✅ Created service directory");
128+
}
129+
130+
if (!fs.existsSync(serviceKotlinPath)) {
131+
const serviceCode = `package com.digitalnomad91.codebuilderadmin
132+
133+
import android.app.Notification
134+
import android.app.NotificationChannel
135+
import android.app.NotificationManager
136+
import android.app.Service
137+
import android.content.Intent
138+
import android.media.projection.MediaProjection
139+
import android.os.Build
140+
import android.os.IBinder
141+
import androidx.core.app.NotificationCompat
142+
import com.digitalnomad91.codebuilderadmin.R
143+
144+
class ScreenRecordService : Service() {
145+
private val CHANNEL_ID = "ScreenRecordChannel"
146+
private var mediaProjection: MediaProjection? = null
147+
148+
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
149+
createNotification()
150+
return START_STICKY
151+
}
152+
153+
private fun createNotification() {
154+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
155+
val channel = NotificationChannel(
156+
CHANNEL_ID,
157+
"Screen Recording",
158+
NotificationManager.IMPORTANCE_LOW
159+
)
160+
val manager = getSystemService(NotificationManager::class.java)
161+
manager.createNotificationChannel(channel)
162+
}
163+
164+
val notification = NotificationCompat.Builder(this, CHANNEL_ID)
165+
.setContentTitle("Screen Recording")
166+
.setContentText("Your screen is being recorded")
167+
.setSmallIcon(R.mipmap.ic_launcher_foreground)
168+
.build()
169+
170+
startForeground(1, notification)
171+
}
172+
173+
override fun onBind(intent: Intent?): IBinder? = null
174+
}
175+
`;
176+
fs.writeFileSync(serviceKotlinPath, serviceCode, "utf8");
177+
console.log("✅ ScreenRecordService.kt created.");
178+
} else {
179+
console.log("✅ ScreenRecordService.kt exists.");
180+
}
181+
};
182+
183+
// Execute all steps
184+
try {
185+
ensurePermissions();
186+
ensureMainActivityModifications();
187+
ensureScreenRecordService();
188+
console.log("🎉 Screen recording setup completed!");
189+
} catch (error) {
190+
console.error("❌ Setup failed:", error);
191+
}

0 commit comments

Comments
 (0)