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
17package com.android.internal.app;
18
19import android.app.AlertDialog;
20import android.content.BroadcastReceiver;
21import android.content.Context;
22import android.content.DialogInterface;
23import android.content.Intent;
24import android.content.IntentFilter;
25import android.os.Bundle;
26import android.os.Handler;
27import android.os.Message;
28import android.widget.Toast;
29import android.util.Log;
30import android.location.LocationManager;
31
32import com.android.internal.R;
33import com.android.internal.location.GpsNetInitiatedHandler;
34
35/**
36 * This activity is shown to the user for him/her to accept or deny network-initiated
37 * requests. It uses the alert dialog style. It will be launched from a notification.
38 */
39public class NetInitiatedActivity extends AlertActivity implements DialogInterface.OnClickListener {
40
41    private static final String TAG = "NetInitiatedActivity";
42
43    private static final boolean DEBUG = true;
44    private static final boolean VERBOSE = false;
45
46    private static final int POSITIVE_BUTTON = AlertDialog.BUTTON_POSITIVE;
47    private static final int NEGATIVE_BUTTON = AlertDialog.BUTTON_NEGATIVE;
48
49    private static final int GPS_NO_RESPONSE_TIME_OUT = 1;
50    // Received ID from intent, -1 when no notification is in progress
51    private int notificationId = -1;
52    private int timeout = -1;
53    private int default_response = -1;
54    private int default_response_timeout = 6;
55
56    /** Used to detect when NI request is received */
57    private BroadcastReceiver mNetInitiatedReceiver = new BroadcastReceiver() {
58        @Override
59        public void onReceive(Context context, Intent intent) {
60            if (DEBUG) Log.d(TAG, "NetInitiatedReceiver onReceive: " + intent.getAction());
61            if (intent.getAction() == GpsNetInitiatedHandler.ACTION_NI_VERIFY) {
62                handleNIVerify(intent);
63            }
64        }
65    };
66
67    private final Handler mHandler = new Handler() {
68        public void handleMessage(Message msg) {
69            switch (msg.what) {
70            case GPS_NO_RESPONSE_TIME_OUT: {
71                if (notificationId != -1) {
72                    sendUserResponse(default_response);
73                }
74                finish();
75            }
76            break;
77            default:
78            }
79        }
80    };
81
82    @Override
83    protected void onCreate(Bundle savedInstanceState) {
84        super.onCreate(savedInstanceState);
85
86        // Set up the "dialog"
87        final Intent intent = getIntent();
88        final AlertController.AlertParams p = mAlertParams;
89        Context context = getApplicationContext();
90        p.mTitle = intent.getStringExtra(GpsNetInitiatedHandler.NI_INTENT_KEY_TITLE);
91        p.mMessage = intent.getStringExtra(GpsNetInitiatedHandler.NI_INTENT_KEY_MESSAGE);
92        p.mPositiveButtonText = String.format(context.getString(R.string.gpsVerifYes));
93        p.mPositiveButtonListener = this;
94        p.mNegativeButtonText = String.format(context.getString(R.string.gpsVerifNo));
95        p.mNegativeButtonListener = this;
96
97        notificationId = intent.getIntExtra(GpsNetInitiatedHandler.NI_INTENT_KEY_NOTIF_ID, -1);
98        timeout = intent.getIntExtra(GpsNetInitiatedHandler.NI_INTENT_KEY_TIMEOUT, default_response_timeout);
99        default_response = intent.getIntExtra(GpsNetInitiatedHandler.NI_INTENT_KEY_DEFAULT_RESPONSE, GpsNetInitiatedHandler.GPS_NI_RESPONSE_ACCEPT);
100        if (DEBUG) Log.d(TAG, "onCreate() : notificationId: " + notificationId + " timeout: " + timeout + " default_response:" + default_response);
101
102        mHandler.sendMessageDelayed(mHandler.obtainMessage(GPS_NO_RESPONSE_TIME_OUT), (timeout * 1000));
103        setupAlert();
104    }
105
106    @Override
107    protected void onResume() {
108        super.onResume();
109        if (DEBUG) Log.d(TAG, "onResume");
110        registerReceiver(mNetInitiatedReceiver, new IntentFilter(GpsNetInitiatedHandler.ACTION_NI_VERIFY));
111    }
112
113    @Override
114    protected void onPause() {
115        super.onPause();
116        if (DEBUG) Log.d(TAG, "onPause");
117        unregisterReceiver(mNetInitiatedReceiver);
118    }
119
120    /**
121     * {@inheritDoc}
122     */
123    public void onClick(DialogInterface dialog, int which) {
124        if (which == POSITIVE_BUTTON) {
125            sendUserResponse(GpsNetInitiatedHandler.GPS_NI_RESPONSE_ACCEPT);
126        }
127        if (which == NEGATIVE_BUTTON) {
128            sendUserResponse(GpsNetInitiatedHandler.GPS_NI_RESPONSE_DENY);
129        }
130
131        // No matter what, finish the activity
132        finish();
133        notificationId = -1;
134    }
135
136    // Respond to NI Handler under GnssLocationProvider, 1 = accept, 2 = deny
137    private void sendUserResponse(int response) {
138        if (DEBUG) Log.d(TAG, "sendUserResponse, response: " + response);
139        LocationManager locationManager = (LocationManager)
140            this.getSystemService(Context.LOCATION_SERVICE);
141        locationManager.sendNiResponse(notificationId, response);
142    }
143
144    private void handleNIVerify(Intent intent) {
145        int notifId = intent.getIntExtra(GpsNetInitiatedHandler.NI_INTENT_KEY_NOTIF_ID, -1);
146        notificationId = notifId;
147
148        if (DEBUG) Log.d(TAG, "handleNIVerify action: " + intent.getAction());
149    }
150
151    private void showNIError() {
152        Toast.makeText(this, "NI error" /* com.android.internal.R.string.usb_storage_error_message */,
153                Toast.LENGTH_LONG).show();
154    }
155}
156