xref: /aosp_15_r20/external/wpa_supplicant_8/src/utils/browser-android.c (revision 03f9172ca588f91df233974f4258bab95191f931)
1*03f9172cSAndroid Build Coastguard Worker /*
2*03f9172cSAndroid Build Coastguard Worker  * Hotspot 2.0 client - Web browser using Android browser
3*03f9172cSAndroid Build Coastguard Worker  * Copyright (c) 2013, Qualcomm Atheros, Inc.
4*03f9172cSAndroid Build Coastguard Worker  *
5*03f9172cSAndroid Build Coastguard Worker  * This software may be distributed under the terms of the BSD license.
6*03f9172cSAndroid Build Coastguard Worker  * See README for more details.
7*03f9172cSAndroid Build Coastguard Worker  */
8*03f9172cSAndroid Build Coastguard Worker 
9*03f9172cSAndroid Build Coastguard Worker #include "includes.h"
10*03f9172cSAndroid Build Coastguard Worker 
11*03f9172cSAndroid Build Coastguard Worker #include "common.h"
12*03f9172cSAndroid Build Coastguard Worker #include "utils/eloop.h"
13*03f9172cSAndroid Build Coastguard Worker #include "wps/http_server.h"
14*03f9172cSAndroid Build Coastguard Worker #include "browser.h"
15*03f9172cSAndroid Build Coastguard Worker 
16*03f9172cSAndroid Build Coastguard Worker 
17*03f9172cSAndroid Build Coastguard Worker struct browser_data {
18*03f9172cSAndroid Build Coastguard Worker 	int success;
19*03f9172cSAndroid Build Coastguard Worker };
20*03f9172cSAndroid Build Coastguard Worker 
21*03f9172cSAndroid Build Coastguard Worker 
browser_timeout(void * eloop_data,void * user_ctx)22*03f9172cSAndroid Build Coastguard Worker static void browser_timeout(void *eloop_data, void *user_ctx)
23*03f9172cSAndroid Build Coastguard Worker {
24*03f9172cSAndroid Build Coastguard Worker 	wpa_printf(MSG_INFO, "Timeout on waiting browser interaction to "
25*03f9172cSAndroid Build Coastguard Worker 		   "complete");
26*03f9172cSAndroid Build Coastguard Worker 	eloop_terminate();
27*03f9172cSAndroid Build Coastguard Worker }
28*03f9172cSAndroid Build Coastguard Worker 
29*03f9172cSAndroid Build Coastguard Worker 
http_req(void * ctx,struct http_request * req)30*03f9172cSAndroid Build Coastguard Worker static void http_req(void *ctx, struct http_request *req)
31*03f9172cSAndroid Build Coastguard Worker {
32*03f9172cSAndroid Build Coastguard Worker 	struct browser_data *data = ctx;
33*03f9172cSAndroid Build Coastguard Worker 	struct wpabuf *resp;
34*03f9172cSAndroid Build Coastguard Worker 	const char *url;
35*03f9172cSAndroid Build Coastguard Worker 	int done = 0;
36*03f9172cSAndroid Build Coastguard Worker 
37*03f9172cSAndroid Build Coastguard Worker 	url = http_request_get_uri(req);
38*03f9172cSAndroid Build Coastguard Worker 	wpa_printf(MSG_INFO, "Browser response received: %s", url);
39*03f9172cSAndroid Build Coastguard Worker 
40*03f9172cSAndroid Build Coastguard Worker 	if (os_strcmp(url, "/") == 0) {
41*03f9172cSAndroid Build Coastguard Worker 		data->success = 1;
42*03f9172cSAndroid Build Coastguard Worker 		done = 1;
43*03f9172cSAndroid Build Coastguard Worker 	} else if (os_strncmp(url, "/osu/", 5) == 0) {
44*03f9172cSAndroid Build Coastguard Worker 		data->success = atoi(url + 5);
45*03f9172cSAndroid Build Coastguard Worker 		done = 1;
46*03f9172cSAndroid Build Coastguard Worker 	}
47*03f9172cSAndroid Build Coastguard Worker 
48*03f9172cSAndroid Build Coastguard Worker 	resp = wpabuf_alloc(1);
49*03f9172cSAndroid Build Coastguard Worker 	if (resp == NULL) {
50*03f9172cSAndroid Build Coastguard Worker 		http_request_deinit(req);
51*03f9172cSAndroid Build Coastguard Worker 		if (done)
52*03f9172cSAndroid Build Coastguard Worker 			eloop_terminate();
53*03f9172cSAndroid Build Coastguard Worker 		return;
54*03f9172cSAndroid Build Coastguard Worker 	}
55*03f9172cSAndroid Build Coastguard Worker 
56*03f9172cSAndroid Build Coastguard Worker 	if (done) {
57*03f9172cSAndroid Build Coastguard Worker 		eloop_cancel_timeout(browser_timeout, NULL, NULL);
58*03f9172cSAndroid Build Coastguard Worker 		eloop_register_timeout(0, 500000, browser_timeout, &data, NULL);
59*03f9172cSAndroid Build Coastguard Worker 	}
60*03f9172cSAndroid Build Coastguard Worker 
61*03f9172cSAndroid Build Coastguard Worker 	http_request_send_and_deinit(req, resp);
62*03f9172cSAndroid Build Coastguard Worker }
63*03f9172cSAndroid Build Coastguard Worker 
64*03f9172cSAndroid Build Coastguard Worker 
hs20_web_browser(const char * url,int ignore_tls)65*03f9172cSAndroid Build Coastguard Worker int hs20_web_browser(const char *url, int ignore_tls)
66*03f9172cSAndroid Build Coastguard Worker {
67*03f9172cSAndroid Build Coastguard Worker 	struct http_server *http;
68*03f9172cSAndroid Build Coastguard Worker 	struct in_addr addr;
69*03f9172cSAndroid Build Coastguard Worker 	struct browser_data data;
70*03f9172cSAndroid Build Coastguard Worker 	pid_t pid;
71*03f9172cSAndroid Build Coastguard Worker 
72*03f9172cSAndroid Build Coastguard Worker 	wpa_printf(MSG_INFO, "Launching Android browser to %s", url);
73*03f9172cSAndroid Build Coastguard Worker 
74*03f9172cSAndroid Build Coastguard Worker 	os_memset(&data, 0, sizeof(data));
75*03f9172cSAndroid Build Coastguard Worker 
76*03f9172cSAndroid Build Coastguard Worker 	if (eloop_init() < 0) {
77*03f9172cSAndroid Build Coastguard Worker 		wpa_printf(MSG_ERROR, "eloop_init failed");
78*03f9172cSAndroid Build Coastguard Worker 		return -1;
79*03f9172cSAndroid Build Coastguard Worker 	}
80*03f9172cSAndroid Build Coastguard Worker 	addr.s_addr = htonl((127 << 24) | 1);
81*03f9172cSAndroid Build Coastguard Worker 	http = http_server_init(&addr, 12345, http_req, &data);
82*03f9172cSAndroid Build Coastguard Worker 	if (http == NULL) {
83*03f9172cSAndroid Build Coastguard Worker 		wpa_printf(MSG_ERROR, "http_server_init failed");
84*03f9172cSAndroid Build Coastguard Worker 		eloop_destroy();
85*03f9172cSAndroid Build Coastguard Worker 		return -1;
86*03f9172cSAndroid Build Coastguard Worker 	}
87*03f9172cSAndroid Build Coastguard Worker 
88*03f9172cSAndroid Build Coastguard Worker 	pid = fork();
89*03f9172cSAndroid Build Coastguard Worker 	if (pid < 0) {
90*03f9172cSAndroid Build Coastguard Worker 		wpa_printf(MSG_ERROR, "fork: %s", strerror(errno));
91*03f9172cSAndroid Build Coastguard Worker 		http_server_deinit(http);
92*03f9172cSAndroid Build Coastguard Worker 		eloop_destroy();
93*03f9172cSAndroid Build Coastguard Worker 		return -1;
94*03f9172cSAndroid Build Coastguard Worker 	}
95*03f9172cSAndroid Build Coastguard Worker 
96*03f9172cSAndroid Build Coastguard Worker 	if (pid == 0) {
97*03f9172cSAndroid Build Coastguard Worker 		/* run the external command in the child process */
98*03f9172cSAndroid Build Coastguard Worker 		char *argv[7];
99*03f9172cSAndroid Build Coastguard Worker 
100*03f9172cSAndroid Build Coastguard Worker 		argv[0] = "browser-android";
101*03f9172cSAndroid Build Coastguard Worker 		argv[1] = "start";
102*03f9172cSAndroid Build Coastguard Worker 		argv[2] = "-a";
103*03f9172cSAndroid Build Coastguard Worker 		argv[3] = "android.intent.action.VIEW";
104*03f9172cSAndroid Build Coastguard Worker 		argv[4] = "-d";
105*03f9172cSAndroid Build Coastguard Worker 		argv[5] = (void *) url;
106*03f9172cSAndroid Build Coastguard Worker 		argv[6] = NULL;
107*03f9172cSAndroid Build Coastguard Worker 
108*03f9172cSAndroid Build Coastguard Worker 		execv("/system/bin/am", argv);
109*03f9172cSAndroid Build Coastguard Worker 		wpa_printf(MSG_ERROR, "execv: %s", strerror(errno));
110*03f9172cSAndroid Build Coastguard Worker 		exit(0);
111*03f9172cSAndroid Build Coastguard Worker 		return -1;
112*03f9172cSAndroid Build Coastguard Worker 	}
113*03f9172cSAndroid Build Coastguard Worker 
114*03f9172cSAndroid Build Coastguard Worker 	eloop_register_timeout(30, 0, browser_timeout, &data, NULL);
115*03f9172cSAndroid Build Coastguard Worker 	eloop_run();
116*03f9172cSAndroid Build Coastguard Worker 	eloop_cancel_timeout(browser_timeout, &data, NULL);
117*03f9172cSAndroid Build Coastguard Worker 	http_server_deinit(http);
118*03f9172cSAndroid Build Coastguard Worker 	eloop_destroy();
119*03f9172cSAndroid Build Coastguard Worker 
120*03f9172cSAndroid Build Coastguard Worker 	wpa_printf(MSG_INFO, "Closing Android browser");
121*03f9172cSAndroid Build Coastguard Worker 	if (system("/system/bin/input keyevent KEYCODE_HOME") != 0) {
122*03f9172cSAndroid Build Coastguard Worker 		wpa_printf(MSG_INFO, "Failed to inject keyevent");
123*03f9172cSAndroid Build Coastguard Worker 	}
124*03f9172cSAndroid Build Coastguard Worker 
125*03f9172cSAndroid Build Coastguard Worker 	return data.success;
126*03f9172cSAndroid Build Coastguard Worker }
127