/*
* Copyright 2012 Artiom Chilaru (http://flexlabs.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.flexlabs.widgets.dualbattery.app;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.text.Html;
import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import com.actionbarsherlock.app.SherlockFragment;
import org.flexlabs.widgets.dualbattery.BatteryLevel;
import org.flexlabs.widgets.dualbattery.Constants;
import org.flexlabs.widgets.dualbattery.R;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class FeedbackFragment extends SherlockFragment {
private EditText feedbackEditor;
private boolean resetFeedback = false;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.feedback_form, null);
feedbackEditor = (EditText)view.findViewById(R.id.feedbackEditor);
feedbackEditor.requestFocus();
view.findViewById(R.id.sendFeedback).setOnClickListener(feedbackListener);
return view;
}
private final View.OnClickListener feedbackListener = new View.OnClickListener() {
@Override
public void onClick(View view) {
CharSequence feedbackText = feedbackEditor.getText();
if (!isFeedbackValid(feedbackText)) {
new AlertDialog.Builder(getActivity())
.setTitle(R.string.app_name)
.setMessage(R.string.feedback_hint)
.setPositiveButton("OK", null)
.show();
return;
}
sendFeedback(getActivity(), feedbackText);
resetFeedback = true;
}
};
@Override
public void onStop() {
super.onStop();
if (resetFeedback)
feedbackEditor.setText(null);
}
@Override
public void onResume() {
super.onResume();
resetFeedback = false;
}
private static boolean isFeedbackValid(CharSequence source) {
if (source == null || source.length() < 15)
return false;
int spaces = 0;
for(int i = 0; i < source.length(); i++) {
if(source.charAt(i) == ' ')
spaces++;
if (spaces > 3)
return true;
}
return false;
}
public static void sendFeedback(Context context, CharSequence feedback) {
Intent intent = new Intent(Intent.ACTION_SEND, Uri.parse("mailto:"));
intent.putExtra(Intent.EXTRA_EMAIL, new String[] { Constants.FeedbackDestination });
intent.putExtra(Intent.EXTRA_SUBJECT, "Dual Battery Widget Feedback (v" + Constants.VERSION + ")");
intent.putExtra(Intent.EXTRA_TEXT, Html.fromHtml(getDeviceDetails(context, feedback)));
intent.setType("message/rfc822");
context.startActivity(Intent.createChooser(intent, "Email"));
}
private static String getDeviceDetails(Context context, CharSequence feedback) {
StringBuilder sb = new StringBuilder(feedback);
sb.append("<br />\n<h4>Device details:</h4>");
sb.append("<br />\n<b>App version:</b> v").append(Constants.VERSION);
sb.append("<br />\n<b>Brand:</b> ").append(Build.MANUFACTURER);
sb.append("<br />\n<b>Model:</b> ").append(Build.MODEL);
sb.append("<br />\n<b>Device:</b> ").append(Build.DEVICE);
sb.append("<br />\n<b>Android version:</b> ").append(Build.VERSION.RELEASE);
sb.append("<br />\n<b>Version details:</b> ").append(Build.VERSION.INCREMENTAL);
Intent intent = context.registerReceiver(null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
Bundle extras = intent.getExtras();
String allKeys = TextUtils.join(", ", extras.keySet());
sb.append("<br />\n<b>Battery intent keys:</b> ").append(allKeys);
sb.append("<br />\n<b>Is Dock supported:</b> ").append(BatteryLevel.getCurrent().is_dockFriendly());
int dockStatus = extras.getInt("dock_status", -1);
String dockStatusStr = "";
switch (dockStatus) {
case 0: dockStatusStr = " (Unknown)"; break;
case 1: dockStatusStr = " (Undocked)"; break;
case 2: dockStatusStr = " (Charging)"; break;
case 3: dockStatusStr = " (Docked)"; break;
case 4: dockStatusStr = " (Discharging)"; break;
}
sb.append("<br />\n<b>Battery dock status</b> ").append(extras.get("dock_status")).append(dockStatusStr);
sb.append("<br />\n<b>Battery dock level</b> ").append(extras.get("dock_level"));
sb.append("<br />\n<b>Kernel:</b> ").append(getFormattedKernelVersion().replace("\n", "<br />\n"));
return sb.toString();
}
private static String getFormattedKernelVersion() {
String procVersionStr;
try {
BufferedReader reader = new BufferedReader(new FileReader("/proc/version"), 256);
try {
procVersionStr = reader.readLine();
} finally {
reader.close();
}
final String PROC_VERSION_REGEX =
"\\w+\\s+" + /* ignore: Linux */
"\\w+\\s+" + /* ignore: version */
"([^\\s]+)\\s+" + /* group 1: 2.6.22-omap1 */
"\\(([^\\s@]+(?:@[^\\s.]+)?)[^)]*\\)\\s+" + /* group 2: (xxxxxx@xxxxx.constant) */
"\\(.*?(?:\\(.*?\\)).*?\\)\\s+" + /* ignore: (gcc ..) */
"([^\\s]+)\\s+" + /* group 3: #26 */
"(?:PREEMPT\\s+)?" + /* ignore: PREEMPT (optional) */
"(.+)"; /* group 4: date */
Pattern p = Pattern.compile(PROC_VERSION_REGEX);
Matcher m = p.matcher(procVersionStr);
if (!m.matches()) {
Log.e(Constants.LOG, "Regex did not match on /proc/version: " + procVersionStr);
return "Unavailable";
} else if (m.groupCount() < 4) {
Log.e(Constants.LOG, "Regex match on /proc/version only returned " + m.groupCount()
+ " groups");
return "Unavailable";
} else {
return (new StringBuilder(m.group(1)).append("\n").append(
m.group(2)).append(" ").append(m.group(3)).append("\n")
.append(m.group(4))).toString();
}
} catch (IOException e) {
Log.e(Constants.LOG, "IO Exception when getting kernel version for Device Info screen", e);
return "Unavailable";
}
}
}