1 /*
2  * Copyright (C) 2007 Google Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.internal.app;
18 
19 import android.app.AlertDialog;
20 import android.compat.annotation.UnsupportedAppUsage;
21 import android.content.BroadcastReceiver;
22 import android.content.Context;
23 import android.content.DialogInterface;
24 import android.content.Intent;
25 import android.content.IntentFilter;
26 import android.location.LocationManagerInternal;
27 import android.os.Bundle;
28 import android.os.Handler;
29 import android.os.Message;
30 import android.util.Log;
31 import android.widget.Toast;
32 
33 import com.android.internal.R;
34 import com.android.internal.location.GpsNetInitiatedHandler;
35 import com.android.server.LocalServices;
36 
37 /**
38  * This activity is shown to the user for him/her to accept or deny network-initiated
39  * requests. It uses the alert dialog style. It will be launched from a notification.
40  */
41 public class NetInitiatedActivity extends AlertActivity implements DialogInterface.OnClickListener {
42 
43     private static final String TAG = "NetInitiatedActivity";
44 
45     private static final boolean DEBUG = true;
46     private static final boolean VERBOSE = false;
47 
48     private static final int POSITIVE_BUTTON = AlertDialog.BUTTON_POSITIVE;
49     private static final int NEGATIVE_BUTTON = AlertDialog.BUTTON_NEGATIVE;
50 
51     private static final int GPS_NO_RESPONSE_TIME_OUT = 1;
52     // Received ID from intent, -1 when no notification is in progress
53     private int notificationId = -1;
54     private int timeout = -1;
55     private int default_response = -1;
56     private int default_response_timeout = 6;
57 
58     /** Used to detect when NI request is received */
59     private BroadcastReceiver mNetInitiatedReceiver = new BroadcastReceiver() {
60         @Override
61         public void onReceive(Context context, Intent intent) {
62             if (DEBUG) Log.d(TAG, "NetInitiatedReceiver onReceive: " + intent.getAction());
63             if (intent.getAction() == GpsNetInitiatedHandler.ACTION_NI_VERIFY) {
64                 handleNIVerify(intent);
65             }
66         }
67     };
68 
69     private final Handler mHandler = new Handler() {
70         public void handleMessage(Message msg) {
71             switch (msg.what) {
72                 case GPS_NO_RESPONSE_TIME_OUT: {
73                     if (notificationId != -1) {
74                         sendUserResponse(default_response);
75                     }
76                     finish();
77                 }
78                 break;
79                 default:
80             }
81         }
82     };
83 
84     @Override
onCreate(Bundle savedInstanceState)85     protected void onCreate(Bundle savedInstanceState) {
86         super.onCreate(savedInstanceState);
87 
88         // Set up the "dialog"
89         final Intent intent = getIntent();
90         final AlertController.AlertParams p = mAlertParams;
91         Context context = getApplicationContext();
92         p.mTitle = intent.getStringExtra(GpsNetInitiatedHandler.NI_INTENT_KEY_TITLE);
93         p.mMessage = intent.getStringExtra(GpsNetInitiatedHandler.NI_INTENT_KEY_MESSAGE);
94         p.mPositiveButtonText = String.format(context.getString(R.string.gpsVerifYes));
95         p.mPositiveButtonListener = this;
96         p.mNegativeButtonText = String.format(context.getString(R.string.gpsVerifNo));
97         p.mNegativeButtonListener = this;
98 
99         notificationId = intent.getIntExtra(GpsNetInitiatedHandler.NI_INTENT_KEY_NOTIF_ID, -1);
100         timeout = intent.getIntExtra(GpsNetInitiatedHandler.NI_INTENT_KEY_TIMEOUT, default_response_timeout);
101         default_response = intent.getIntExtra(GpsNetInitiatedHandler.NI_INTENT_KEY_DEFAULT_RESPONSE, GpsNetInitiatedHandler.GPS_NI_RESPONSE_ACCEPT);
102         if (DEBUG) Log.d(TAG, "onCreate() : notificationId: " + notificationId + " timeout: " + timeout + " default_response:" + default_response);
103 
104         mHandler.sendMessageDelayed(mHandler.obtainMessage(GPS_NO_RESPONSE_TIME_OUT), (timeout * 1000));
105         setupAlert();
106     }
107 
108     @Override
onResume()109     protected void onResume() {
110         super.onResume();
111         if (DEBUG) Log.d(TAG, "onResume");
112         registerReceiver(mNetInitiatedReceiver, new IntentFilter(GpsNetInitiatedHandler.ACTION_NI_VERIFY));
113     }
114 
115     @Override
onPause()116     protected void onPause() {
117         super.onPause();
118         if (DEBUG) Log.d(TAG, "onPause");
119         unregisterReceiver(mNetInitiatedReceiver);
120     }
121 
122     /**
123      * {@inheritDoc}
124      */
onClick(DialogInterface dialog, int which)125     public void onClick(DialogInterface dialog, int which) {
126         if (which == POSITIVE_BUTTON) {
127             sendUserResponse(GpsNetInitiatedHandler.GPS_NI_RESPONSE_ACCEPT);
128         }
129         if (which == NEGATIVE_BUTTON) {
130             sendUserResponse(GpsNetInitiatedHandler.GPS_NI_RESPONSE_DENY);
131         }
132 
133         // No matter what, finish the activity
134         finish();
135         notificationId = -1;
136     }
137 
138     // Respond to NI Handler under GnssLocationProvider, 1 = accept, 2 = deny
sendUserResponse(int response)139     private void sendUserResponse(int response) {
140         if (DEBUG) Log.d(TAG, "sendUserResponse, response: " + response);
141         LocationManagerInternal lm = LocalServices.getService(LocationManagerInternal.class);
142         lm.sendNiResponse(notificationId, response);
143     }
144 
145     @UnsupportedAppUsage
handleNIVerify(Intent intent)146     private void handleNIVerify(Intent intent) {
147         int notifId = intent.getIntExtra(GpsNetInitiatedHandler.NI_INTENT_KEY_NOTIF_ID, -1);
148         notificationId = notifId;
149 
150         if (DEBUG) Log.d(TAG, "handleNIVerify action: " + intent.getAction());
151     }
152 
showNIError()153     private void showNIError() {
154         Toast.makeText(this, "NI error" /* com.android.internal.R.string.usb_storage_error_message */,
155                 Toast.LENGTH_LONG).show();
156     }
157 }
158