• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  * Copyright (C) 2016 Mopria Alliance, Inc.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 package com.android.bips.ui;
19 
20 import android.annotation.SuppressLint;
21 import android.app.AlertDialog;
22 import android.content.Context;
23 import android.os.Bundle;
24 import android.text.Editable;
25 import android.text.TextWatcher;
26 import android.util.Log;
27 import android.view.KeyEvent;
28 import android.view.View;
29 import android.view.Window;
30 import android.view.WindowManager;
31 import android.view.inputmethod.EditorInfo;
32 import android.view.inputmethod.InputMethodManager;
33 import android.widget.Button;
34 import android.widget.ProgressBar;
35 import android.widget.TextView;
36 
37 import com.android.bips.R;
38 import com.android.bips.discovery.DiscoveredPrinter;
39 import com.android.bips.discovery.ManualDiscovery;
40 
41 import java.util.regex.Matcher;
42 import java.util.regex.Pattern;
43 
44 /**
45  * Allows the user to enter printer address manually
46  */
47 class AddManualPrinterDialog extends AlertDialog implements TextWatcher,
48         TextView.OnEditorActionListener, View.OnKeyListener {
49     private static final String TAG = AddManualPrinterDialog.class.getSimpleName();
50     private static final boolean DEBUG = false;
51 
52     /**
53      * A regex that matches IP addresses and domain names like "192.168.1.101" and
54      * "printer1.company.com"
55      */
56     private static final String NAME_IP_REGEX =
57             "[a-zA-Z0-9]+(\\-[a-zA-Z0-9]+)*(\\.[a-zA-Z0-9]+(\\-[a-zA-Z0-9]+)*)*";
58     private static final String HOSTNAME_REGEXP = "^" + NAME_IP_REGEX + "$";
59     private static final Pattern HOSTNAME_PATTERN = Pattern.compile(HOSTNAME_REGEXP);
60 
61     private final ManualDiscovery mDiscovery;
62     private TextView mHostnameView;
63     private Button mAddButton;
64     private ProgressBar mProgressBar;
65 
AddManualPrinterDialog(Context context, ManualDiscovery discovery)66     AddManualPrinterDialog(Context context, ManualDiscovery discovery) {
67         super(context);
68         mDiscovery = discovery;
69     }
70 
71     @SuppressLint("InflateParams")
72     @Override
onCreate(Bundle savedInstanceState)73     protected void onCreate(Bundle savedInstanceState) {
74         if (DEBUG) Log.d(TAG, "onCreate");
75         View view = getLayoutInflater().inflate(R.layout.manual_printer_add, null);
76         setView(view);
77         setTitle(R.string.add_manual_printer);
78         setButton(AlertDialog.BUTTON_NEGATIVE, getContext().getString(android.R.string.cancel),
79                 (OnClickListener) null);
80         setButton(AlertDialog.BUTTON_POSITIVE, getContext().getString(R.string.add),
81                 (OnClickListener) null);
82 
83         super.onCreate(savedInstanceState);
84         mAddButton = getButton(AlertDialog.BUTTON_POSITIVE);
85         mHostnameView = (TextView) findViewById(R.id.hostname);
86         mProgressBar = (ProgressBar) findViewById(R.id.progress);
87 
88         mAddButton.setOnClickListener(view1 -> addPrinter());
89 
90         // Update add button as contents change
91         mHostnameView.addTextChangedListener(this);
92         mHostnameView.setOnEditorActionListener(this);
93         mHostnameView.setOnKeyListener(this);
94 
95         // Force open keyboard if appropriate
96         openKeyboard(mHostnameView);
97 
98         updateButtonState();
99     }
100 
openKeyboard(TextView view)101     private void openKeyboard(TextView view) {
102         Window window = getWindow();
103         if (window != null) {
104             window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
105         }
106 
107         view.requestFocus();
108         InputMethodManager imm = (InputMethodManager) getContext()
109                 .getSystemService(Context.INPUT_METHOD_SERVICE);
110         imm.showSoftInput(view, InputMethodManager.SHOW_IMPLICIT);
111     }
112 
updateButtonState()113     private void updateButtonState() {
114         String hostname = mHostnameView.getText().toString();
115         Matcher hostMatch = HOSTNAME_PATTERN.matcher(hostname);
116 
117         mAddButton.setEnabled(hostMatch.matches());
118     }
119 
120     /** Attempt to add the printer based on current data */
addPrinter()121     private void addPrinter() {
122         // Disable other actions while we are checking
123         mAddButton.setEnabled(false);
124         mHostnameView.setEnabled(false);
125         mProgressBar.setVisibility(View.VISIBLE);
126 
127         // Begin an attempt to add the printer
128         mDiscovery.addManualPrinter(mHostnameView.getText().toString(),
129                 new ManualDiscovery.PrinterAddCallback() {
130                     @Override
131                     public void onFound(DiscoveredPrinter printer, boolean supported) {
132                         if (supported) {
133                             // Success case
134                             dismiss();
135                         } else {
136                             error(getContext().getString(R.string.printer_not_supported));
137                         }
138                     }
139 
140                     @Override
141                     public void onNotFound() {
142                         error(getContext().getString(R.string.no_printer_found));
143                     }
144                 });
145     }
146 
147     /** Inform user of error and allow them to correct it */
error(String message)148     private void error(String message) {
149         mProgressBar.setVisibility(View.GONE);
150         mHostnameView.setError(message);
151         mHostnameView.setEnabled(true);
152         openKeyboard(mHostnameView);
153     }
154 
155     @Override
beforeTextChanged(CharSequence charSequence, int start, int count, int after)156     public void beforeTextChanged(CharSequence charSequence, int start, int count, int after) {
157     }
158 
159     @Override
onTextChanged(CharSequence charSequence, int start, int before, int count)160     public void onTextChanged(CharSequence charSequence, int start, int before, int count) {
161     }
162 
163     @Override
afterTextChanged(Editable editable)164     public void afterTextChanged(Editable editable) {
165         updateButtonState();
166     }
167 
168     @Override
onEditorAction(TextView textView, int id, KeyEvent keyEvent)169     public boolean onEditorAction(TextView textView, int id, KeyEvent keyEvent) {
170         if (id == EditorInfo.IME_ACTION_DONE && mAddButton.isEnabled()) {
171             addPrinter();
172             return true;
173         }
174         return false;
175     }
176 
177     @Override
onKey(View view, int keyCode, KeyEvent keyEvent)178     public boolean onKey(View view, int keyCode, KeyEvent keyEvent) {
179         if (keyCode == KeyEvent.KEYCODE_ENTER && mAddButton.isEnabled()) {
180             addPrinter();
181             return true;
182         }
183         return false;
184     }
185 }