You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

584 lines
21 KiB
Java

package com.langerhans.one.utils;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Scanner;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserFactory;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.content.res.XModuleResources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Bitmap.CompressFormat;
import android.os.Build;
import android.provider.Settings;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;
import com.htc.preference.HtcListPreference;
import com.htc.preference.HtcMultiSelectListPreference;
import com.htc.preference.HtcPreference;
import com.htc.preference.HtcPreferenceActivity;
import com.htc.preference.HtcPreferenceCategory;
import com.htc.preference.HtcPreferenceFragment;
import com.htc.preference.HtcPreferenceGroup;
import com.htc.preference.HtcPreferenceScreen;
import com.langerhans.one.PrefsFragment;
import com.langerhans.one.R;
import com.stericson.RootTools.RootTools;
import com.stericson.RootTools.execution.CommandCapture;
public class Helpers {
static DocumentBuilderFactory dbf;
static DocumentBuilder db;
static Document doc = null;
static Element eQS;
public static Map<String, String> l10n = null;
public static String cLang = "";
@SuppressLint("SdCardPath")
public static String dataPath = "/data/data/com.langerhans.one/files/";
public static String buildVersion = "JENKINSBUILDNUMBERGOESHERE";
private static boolean preloadLang(String lang) {
try {
if (l10n == null) {
FileInputStream in_s = new FileInputStream(Helpers.dataPath + "values-" + lang + "/strings.xml");
XmlPullParser parser = XmlPullParserFactory.newInstance().newPullParser();
l10n = new HashMap<String, String>();
parser.setInput(in_s, null);
int eventType = parser.getEventType();
while ((eventType = parser.next()) != XmlPullParser.END_DOCUMENT)
if (eventType == XmlPullParser.START_TAG)
if (parser.getName().equalsIgnoreCase("string"))
l10n.put(parser.getAttributeValue(null, "name"), parser.nextText().replace("\\'", "'").replace("\\\"", "\"").replace("\\n", "\n"));
cLang = lang;
}
return true;
} catch (Exception e) {
cLang = "not_found";
//e.printStackTrace();
}
return false;
}
public static String l10n(Context ctx, int resId) {
if (resId != 0)
return l10n(ctx, ctx.getResources().getResourceEntryName(resId));
else
return "???";
}
public static String l10n(Context ctx, String resName) {
String lang_full = Locale.getDefault().toString();
String lang = Locale.getDefault().getLanguage();
boolean allowFallback = true;
if (lang_full.equals("zh_HK")) allowFallback = false;
String newStr = null;
if (!lang.equals("") && !lang.equals("en") && !lang_full.contains("en_") && !cLang.equals("not_found"))
if (preloadLang(lang_full))
newStr = l10n.get(resName);
else if (allowFallback && preloadLang(lang))
newStr = l10n.get(resName);
if (newStr != null) return newStr;
int resId = ctx.getResources().getIdentifier(resName, "string", ctx.getPackageName());
if (resId != 0)
return ctx.getResources().getString(resId);
else
return "???";
}
public static String xl10n(XModuleResources modRes, int resId) {
if (resId != 0)
return xl10n(modRes, modRes.getResourceEntryName(resId));
else
return "???";
}
public static String xl10n(XModuleResources modRes, String resName) {
String lang_full = Locale.getDefault().toString();
String lang = Locale.getDefault().getLanguage();
boolean allowFallback = true;
if (lang_full.equals("zh_HK")) allowFallback = false;
String newStr = null;
if (!lang.equals("") && !lang.equals("en") && !lang_full.contains("en_") && !cLang.equals("not_found"))
if (preloadLang(lang_full))
newStr = l10n.get(resName);
else if (allowFallback && preloadLang(lang))
newStr = l10n.get(resName);
if (newStr != null) return newStr;
int resId = modRes.getIdentifier(resName, "string", "com.langerhans.one");
if (resId != 0)
return modRes.getString(resId);
else
return "???";
}
public static String[] xl10n_array(XModuleResources modRes, int resId) {
TypedArray ids = modRes.obtainTypedArray(resId);
List<String> array = new ArrayList<String>();
for (int i = 0; i < ids.length(); i++) {
int id = ids.getResourceId(i, 0);
if (id != 0)
array.add(xl10n(modRes, id));
else
array.add("???");
}
ids.recycle();
return array.toArray(new String[array.size()]);
}
private static ArrayList<HtcPreference> getPreferenceList(HtcPreference p, ArrayList<HtcPreference> list) {
if (p instanceof HtcPreferenceCategory || p instanceof HtcPreferenceScreen) {
HtcPreferenceGroup pGroup = (HtcPreferenceGroup) p;
int pCount = pGroup.getPreferenceCount();
for (int i = 0; i < pCount; i++)
getPreferenceList(pGroup.getPreference(i), list);
}
list.add(p);
return list;
}
public static void applyLang(HtcPreferenceActivity act, HtcPreferenceFragment frag) {
ArrayList<HtcPreference> list;
if (frag == null)
list = getPreferenceList(act.getPreferenceScreen(), new ArrayList<HtcPreference>());
else
list = getPreferenceList(frag.getPreferenceScreen(), new ArrayList<HtcPreference>());
for (HtcPreference p: list) {
int titleResId = p.getTitleRes();
if (titleResId != 0) p.setTitle(l10n(act, titleResId));
CharSequence summ = p.getSummary();
if (summ != null && summ != "") {
if (titleResId == R.string.array_global_actions_launch || titleResId == R.string.array_global_actions_toggle) {
p.setSummary(l10n(act, "notselected"));
} else {
String titleResName = act.getResources().getResourceEntryName(titleResId);
String summResName = titleResName.replace("_title", "_summ");
p.setSummary(l10n(act, summResName));
}
}
if (p.getClass() == HtcListPreference.class || p.getClass() == HtcListPreferencePlus.class || p.getClass() == ImageListPreference.class || p.getClass() == HtcMultiSelectListPreference.class) {
String titleResName = act.getResources().getResourceEntryName(titleResId);
String entriesResName;
if (titleResName.equals("controls_vol_up_media_title") || titleResName.equals("controls_vol_down_media_title"))
entriesResName = "media_action";
else if (titleResName.equals("controls_vol_up_cam_title") || titleResName.equals("controls_vol_down_cam_title"))
entriesResName = "cam_actions";
else if (titleResName.equals("controls_extendedpanel_left_title") || titleResName.equals("controls_extendedpanel_right_title"))
entriesResName = "extendedpanel_actions";
else if (titleResName.contains("sense_") || titleResName.contains("controls_"))
entriesResName = "global_actions";
else if (titleResName.contains("wakegestures_"))
entriesResName = "wakegest_actions";
else if (titleResId == R.string.array_global_actions_toggle)
entriesResName = "global_toggles";
else
entriesResName = titleResName.replace("_title", "");
int arrayId = act.getResources().getIdentifier(entriesResName, "array", act.getPackageName());
if (arrayId != 0) {
TypedArray ids = act.getResources().obtainTypedArray(arrayId);
List<String> newEntries = new ArrayList<String>();
for (int i = 0; i < ids.length(); i++) {
int id = ids.getResourceId(i, 0);
if (id != 0)
newEntries.add(l10n(act, id));
else
newEntries.add("???");
}
ids.recycle();
if (p.getClass() == HtcMultiSelectListPreference.class) {
HtcMultiSelectListPreference lst = ((HtcMultiSelectListPreference)p);
lst.setEntries(newEntries.toArray(new CharSequence[newEntries.size()]));
lst.setDialogTitle(l10n(act, titleResId));
} else {
HtcListPreference lst = ((HtcListPreference)p);
lst.setEntries(newEntries.toArray(new CharSequence[newEntries.size()]));
lst.setDialogTitle(l10n(act, titleResId));
}
}
}
}
}
/**
* Gets the CID of the device.
* @return The CID
*/
@SuppressWarnings("deprecation")
public static String getCID() {
String cidXML;
InputStream inputstream = null;
try {
inputstream = Runtime.getRuntime().exec("/system/bin/getprop ro.cid").getInputStream();
Scanner scan = new Scanner(inputstream);
String propval = scan.useDelimiter("\\A").nextLine();
scan.close();
List<String> availACC = new ArrayList<String>();
availACC = RootTools.sendShell("ls /system/customize/ACC/", -1);
for (int i = 0; i < availACC.size(); i++)
if (availACC.get(i).equals(propval + ".xml")) {
cidXML = propval;
return cidXML;
}
cidXML = "default";
return cidXML;
} catch (Exception e) {
e.printStackTrace();
}
return "ERR_NO_CID";
}
/**
* Parse the ACC XML file for the given CID
* @param cidXML The CID of the device
* @return A String Array that holds all currently used tiles
*/
@SuppressWarnings("deprecation")
public static String[] parseACC(String cidXML, Context ctx) {
dbf = DocumentBuilderFactory.newInstance();
try {
db = dbf.newDocumentBuilder();
String dir = ctx.getCacheDir().getAbsolutePath();
CommandCapture command = new CommandCapture(0,
"cp /system/customize/ACC/" + cidXML + ".xml " + dir + "/tmp.xml",
"chmod 777 " + dir + "/tmp.xml");
RootTools.getShell(true).add(command).waitForFinish();
File file = new File(dir + "/tmp.xml");
try {
InputSource is = new InputSource(new FileReader(file));
doc = db.parse(is);
doc.getDocumentElement().normalize();
NodeList allItems = doc.getElementsByTagName("item");
for (int i = 0; i < allItems.getLength(); i++) {
Node node = allItems.item(i);
if (node.getAttributes().getNamedItem("name").getNodeValue().equals("quick_setting_items")) {
eQS = (Element) node;
NodeList qsOrder = eQS.getElementsByTagName("int");
String[] qsList = new String[qsOrder.getLength()];
for (int j = 0; j < qsOrder.getLength(); j++)
qsList[j] = qsOrder.item(j).getChildNodes().item(0).getNodeValue();
//Remove tmp.xml
RootTools.sendShell("rm " + dir + "/tmp.xml", 0);
return qsList;
}
}
} catch (Exception e) {
e.printStackTrace();
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* Writes the new ACC XML file.
* @param cidXML The CID for naming the file. Should be the same as we read from.
* @param adapter The ArrayAdapter that holds the tile order to be saved.
*/
public static void writeACC(String cidXML, ArrayAdapter<String> adapter, Context ctx) {
if (doc == null) return; else try {
removeAllChildren(eQS);
for (int i = 0; i<adapter.getCount(); i++) {
Element e = doc.createElement("int");
e.appendChild(doc.createTextNode(adapter.getItem(i)));
eQS.appendChild(e);
}
String dir = ctx.getCacheDir().getAbsolutePath();
File file = new File(dir + "/new.xml");
file.createNewFile();
if (file.exists()) {
OutputStream fo = new FileOutputStream(file);
fo.write(getStringFromDoc(doc).getBytes());
fo.close();
CommandCapture command = new CommandCapture(0,
"mount -o rw,remount /system",
"cat " + dir + "/new.xml > /system/customize/ACC/" + cidXML + ".xml",
"rm " + dir + "/tmp.xml",
"rm " + dir + "/new.xml",
"mount -o ro,remount /system"
);
RootTools.getShell(true).add(command).waitForFinish();
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* Removes all children from the given XML node
* @param node The node from which the children should be removed
*/
public static void removeAllChildren(Node node) {
for (Node child; (child = node.getFirstChild()) != null; node.removeChild(child));
}
/**
* Gets the String representation from an XML document
* @param doc The XML document
* @return The String representation
*/
public static String getStringFromDoc(org.w3c.dom.Document doc) {
try {
Transformer transformer = TransformerFactory.newInstance().newTransformer();
StreamResult result = new StreamResult(new StringWriter());
DOMSource source = new DOMSource(doc);
transformer.transform(source, result);
return result.getWriter().toString();
} catch(TransformerException ex) {
ex.printStackTrace();
return null;
}
}
/**
* Maps a given EQS name to it's ID
* @param name EQS tile name
* @return EQS tile ID
*/
public static String mapStringToID(Context context, String name) {
Resources res = context.getResources();
if (name.equals(res.getText(R.string.eqs_user_card))) return "0";
else if (name.equals(res.getText(R.string.eqs_brightness))) return "1";
else if (name.equals(res.getText(R.string.eqs_settings))) return "2";
else if (name.equals(res.getText(R.string.eqs_wifi))) return "3";
else if (name.equals(res.getText(R.string.eqs_bluetooth))) return "4";
else if (name.equals(res.getText(R.string.eqs_airplane))) return "5";
else if (name.equals(res.getText(R.string.eqs_power_save))) return "6";
else if (name.equals(res.getText(R.string.eqs_rotation))) return "7";
else if (name.equals(res.getText(R.string.eqs_mobile_data))) return "8";
else if (name.equals(res.getText(R.string.eqs_sound_profile))) return "9";
else if (name.equals(res.getText(R.string.eqs_wifi_hotspot))) return "10";
else if (name.equals(res.getText(R.string.eqs_screenshot))) return "11";
else if (name.equals(res.getText(R.string.eqs_gps))) return "12";
else if (name.equals(res.getText(R.string.eqs_roaming))) return "13";
else if (name.equals(res.getText(R.string.eqs_media_output))) return "14";
else if (name.equals(res.getText(R.string.eqs_auto_sync))) return "15";
else if (name.equals(res.getText(R.string.eqs_roaming_setting))) return "16";
else if (name.equals(res.getText(R.string.eqs_music_channel))) return "17";
else if (name.equals(res.getText(R.string.eqs_ringtone))) return "18";
else if (name.equals(res.getText(R.string.eqs_timeout))) return "19";
else if (name.equals(res.getText(R.string.eqs_syn_all_fake))) return "20";
else if (name.equals(res.getText(R.string.eqs_apn))) return "21";
return "0";
}
/**
* Maps an EQS tile ID to it's name
* @param id EQS tile ID
* @return EQS tile name
*/
public static int mapIDToString(int id) {
switch (id) {
case 0:
return R.string.eqs_user_card;
case 1:
return R.string.eqs_brightness;
case 2:
return R.string.eqs_settings;
case 3:
return R.string.eqs_wifi;
case 4:
return R.string.eqs_bluetooth;
case 5:
return R.string.eqs_airplane;
case 6:
return R.string.eqs_power_save;
case 7:
return R.string.eqs_rotation;
case 8:
return R.string.eqs_mobile_data;
case 9:
return R.string.eqs_sound_profile;
case 10:
return R.string.eqs_wifi_hotspot;
case 11:
return R.string.eqs_screenshot;
case 12:
return R.string.eqs_gps;
case 13:
return R.string.eqs_roaming;
case 14:
return R.string.eqs_media_output;
case 15:
return R.string.eqs_auto_sync;
case 16:
return R.string.eqs_roaming_setting;
case 17:
return R.string.eqs_music_channel;
case 18:
return R.string.eqs_ringtone;
case 19:
return R.string.eqs_timeout;
case 20:
return R.string.eqs_syn_all_fake;
case 21:
return R.string.eqs_apn;
}
return R.string.dummy;
}
public static boolean isXposedInstalled(Context ctx) {
PackageManager pm = ctx.getPackageManager();
boolean installed = false;
try {
pm.getPackageInfo("de.robv.android.xposed.installer", PackageManager.GET_ACTIVITIES);
installed = true;
} catch (PackageManager.NameNotFoundException e) {
installed = false;
}
return installed;
}
public static String getSenseVersion() {
return String.valueOf(com.htc.util.phone.ProjectUtils.getSenseVersion());
}
public static TextView createCenteredText(Context ctx, int resId) {
TextView centerMsg = new TextView(ctx);
centerMsg.setText(l10n(ctx, resId));
centerMsg.setGravity(Gravity.CENTER_HORIZONTAL);
centerMsg.setPadding(0, 60, 0, 60);
centerMsg.setTextSize(18.0f);
centerMsg.setTextColor(ctx.getResources().getColor(android.R.color.primary_text_light));
return centerMsg;
}
public static boolean isNotM7() {
return (!Build.DEVICE.contains("m7")); //|| Build.DEVICE.equals("m7cdug") || Build.DEVICE.equals("m7cdwg")
}
public static void processResult(Activity act, int requestCode, int resultCode, Intent data) {
if (requestCode != 7350) return;
if (resultCode == Activity.RESULT_OK) {
Bitmap icon = null;
Intent.ShortcutIconResource iconResId = data.getParcelableExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE);
if (iconResId != null) try {
Context ctx = act.createPackageContext(iconResId.packageName, Context.CONTEXT_IGNORE_SECURITY);
icon = BitmapFactory.decodeResource(ctx.getResources(), ctx.getResources().getIdentifier(iconResId.resourceName, "drawable", iconResId.packageName));
} catch (Exception e) {}
if (icon == null) icon = (Bitmap)data.getParcelableExtra(Intent.EXTRA_SHORTCUT_ICON);
if (icon != null && PrefsFragment.lastShortcutKey != null) try {
String dir = act.getFilesDir() + "/shortcuts";
String fileName = dir + "/" + PrefsFragment.lastShortcutKey + ".png";
File shortcutsDir = new File(dir);
shortcutsDir.mkdirs();
File shortcutFileName = new File(fileName);
FileOutputStream shortcutOutStream = new FileOutputStream(shortcutFileName);
if (icon.compress(CompressFormat.PNG, 100, shortcutOutStream))
PrefsFragment.prefs.edit().putString(PrefsFragment.lastShortcutKey + "_icon", shortcutFileName.getAbsolutePath()).commit();
shortcutOutStream.close();
} catch (Exception e) {
e.printStackTrace();
}
if (PrefsFragment.lastShortcutKey != null) {
if (PrefsFragment.lastShortcutKeyContents != null) PrefsFragment.prefs.edit().putString(PrefsFragment.lastShortcutKey, PrefsFragment.lastShortcutKeyContents).commit();
String shortcutName = data.getStringExtra(Intent.EXTRA_SHORTCUT_NAME);
if (shortcutName != null) PrefsFragment.prefs.edit().putString(PrefsFragment.lastShortcutKey + "_name", shortcutName).commit();
Intent shortcutIntent = (Intent)data.getParcelableExtra(Intent.EXTRA_SHORTCUT_INTENT);
if (shortcutIntent != null) PrefsFragment.prefs.edit().putString(PrefsFragment.lastShortcutKey + "_intent", shortcutIntent.toUri(0)).commit();
}
if (PrefsFragment.shortcutDlg != null) PrefsFragment.shortcutDlg.dismiss();
}
}
public static ArrayList<View> getChildViewsRecursive(View view) {
if (view instanceof ViewGroup) {
ArrayList<View> list2 = new ArrayList<View>();
ViewGroup viewgroup = (ViewGroup)view;
int i = 0;
do {
if (i >= viewgroup.getChildCount()) return list2;
View view1 = viewgroup.getChildAt(i);
ArrayList<View> list3 = new ArrayList<View>();
list3.add(view);
list3.addAll(getChildViewsRecursive(view1));
list2.addAll(list3);
i++;
} while (true);
} else {
ArrayList<View> list1 = new ArrayList<View>();
list1.add(view);
return list1;
}
}
public static boolean getHTCHaptic(Context ctx) {
Boolean isHapticAllowed = true;
try {
boolean powersaver = (Settings.System.getInt(ctx.getContentResolver(), "user_powersaver_enable", 0) == 1);
boolean haptic = (Settings.Secure.getInt(ctx.getContentResolver(), "powersaver_haptic_feedback", 1) == 1);
if (powersaver && haptic) isHapticAllowed = false;
} catch (Exception e) {}
return isHapticAllowed;
}
public static String getNextAlarm(Context ctx) {
if (ctx != null)
return Settings.System.getString(ctx.getContentResolver(), Settings.System.NEXT_ALARM_FORMATTED);
else
return null;
}
public static long getNextAlarmTime(Context ctx) {
if (ctx != null)
return Settings.System.getLong(ctx.getContentResolver(), "next_alarm_time", -1);
else
return -1;
}
}