diff options
Diffstat (limited to 'src/eu/siacs/conversations/utils')
-rw-r--r-- | src/eu/siacs/conversations/utils/CryptoHelper.java | 9 | ||||
-rw-r--r-- | src/eu/siacs/conversations/utils/DNSHelper.java | 50 | ||||
-rw-r--r-- | src/eu/siacs/conversations/utils/ExifHelper.java | 161 | ||||
-rw-r--r-- | src/eu/siacs/conversations/utils/PhoneHelper.java | 8 | ||||
-rw-r--r-- | src/eu/siacs/conversations/utils/UIHelper.java | 207 |
5 files changed, 187 insertions, 248 deletions
diff --git a/src/eu/siacs/conversations/utils/CryptoHelper.java b/src/eu/siacs/conversations/utils/CryptoHelper.java index a28b519e..47595c6e 100644 --- a/src/eu/siacs/conversations/utils/CryptoHelper.java +++ b/src/eu/siacs/conversations/utils/CryptoHelper.java @@ -5,7 +5,6 @@ import java.nio.charset.Charset; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; -import java.util.Arrays; import eu.siacs.conversations.entities.Account; import android.util.Base64; @@ -28,9 +27,11 @@ public class CryptoHelper { } public static byte[] hexToBytes(String hexString) { - byte[] array = new BigInteger(hexString, 16).toByteArray(); - if (array[0] == 0) { - array = Arrays.copyOfRange(array, 1, array.length); + int len = hexString.length(); + byte[] array = new byte[len / 2]; + for (int i = 0; i < len; i += 2) { + array[i / 2] = (byte) ((Character.digit(hexString.charAt(i), 16) << 4) + Character + .digit(hexString.charAt(i + 1), 16)); } return array; } diff --git a/src/eu/siacs/conversations/utils/DNSHelper.java b/src/eu/siacs/conversations/utils/DNSHelper.java index c51a75ac..f101e883 100644 --- a/src/eu/siacs/conversations/utils/DNSHelper.java +++ b/src/eu/siacs/conversations/utils/DNSHelper.java @@ -33,7 +33,7 @@ public class DNSHelper { for (String dnsserver : dns) { InetAddress ip = InetAddress.getByName(dnsserver); Bundle b = queryDNS(host, ip); - if (b.containsKey("name")) { + if (b.containsKey("values")) { return b; } else if (b.containsKey("error") && "nosrv".equals(b.getString("error", null))) { @@ -45,7 +45,7 @@ public class DNSHelper { } public static Bundle queryDNS(String host, InetAddress dnsServer) { - Bundle namePort = new Bundle(); + Bundle bundle = new Bundle(); try { String qname = "_xmpp-client._tcp." + host; Log.d(Config.LOGTAG, @@ -133,42 +133,28 @@ public class DNSHelper { } if (result.size() == 0) { - namePort.putString("error", "nosrv"); - return namePort; + bundle.putString("error", "nosrv"); + return bundle; } - // we now have a list of servers to try :-) - - // classic name/port pair - String resultName = result.get(0).getName(); - namePort.putString("name", resultName); - namePort.putInt("port", result.get(0).getPort()); - - if (ips4.containsKey(resultName)) { - // we have an ip! - ArrayList<String> ip = ips4.get(resultName); - Collections.shuffle(ip, rnd); - namePort.putString("ipv4", ip.get(0)); - } - if (ips6.containsKey(resultName)) { - ArrayList<String> ip = ips6.get(resultName); - Collections.shuffle(ip, rnd); - namePort.putString("ipv6", ip.get(0)); - } - - // add all other records - int i = 0; + ArrayList<Bundle> values = new ArrayList<Bundle>(); for (SRV srv : result) { - namePort.putString("name" + i, srv.getName()); - namePort.putInt("port" + i, srv.getPort()); - i++; + Bundle namePort = new Bundle(); + namePort.putString("name", srv.getName()); + namePort.putInt("port", srv.getPort()); + if (ips4.containsKey(srv.getName())) { + ArrayList<String> ip = ips4.get(srv.getName()); + Collections.shuffle(ip, rnd); + namePort.putString("ipv4", ip.get(0)); + } + values.add(namePort); } - + bundle.putParcelableArrayList("values", values); } catch (SocketTimeoutException e) { - namePort.putString("error", "timeout"); + bundle.putString("error", "timeout"); } catch (Exception e) { - namePort.putString("error", "unhandled"); + bundle.putString("error", "unhandled"); } - return namePort; + return bundle; } final protected static char[] hexArray = "0123456789ABCDEF".toCharArray(); diff --git a/src/eu/siacs/conversations/utils/ExifHelper.java b/src/eu/siacs/conversations/utils/ExifHelper.java new file mode 100644 index 00000000..ceda7293 --- /dev/null +++ b/src/eu/siacs/conversations/utils/ExifHelper.java @@ -0,0 +1,161 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * 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 eu.siacs.conversations.utils; + +import android.util.Log; + +import java.io.IOException; +import java.io.InputStream; + +public class ExifHelper { + private static final String TAG = "CameraExif"; + + public static int getOrientation(InputStream is) { + if (is == null) { + return 0; + } + + byte[] buf = new byte[8]; + int length = 0; + + // ISO/IEC 10918-1:1993(E) + while (read(is, buf, 2) && (buf[0] & 0xFF) == 0xFF) { + int marker = buf[1] & 0xFF; + + // Check if the marker is a padding. + if (marker == 0xFF) { + continue; + } + + // Check if the marker is SOI or TEM. + if (marker == 0xD8 || marker == 0x01) { + continue; + } + // Check if the marker is EOI or SOS. + if (marker == 0xD9 || marker == 0xDA) { + return 0; + } + + // Get the length and check if it is reasonable. + if (!read(is, buf, 2)) { + return 0; + } + length = pack(buf, 0, 2, false); + if (length < 2) { + Log.e(TAG, "Invalid length"); + return 0; + } + length -= 2; + + // Break if the marker is EXIF in APP1. + if (marker == 0xE1 && length >= 6) { + if (!read(is, buf, 6)) return 0; + length -= 6; + if (pack(buf, 0, 4, false) == 0x45786966 && + pack(buf, 4, 2, false) == 0) { + break; + } + } + + // Skip other markers. + try { + is.skip(length); + } catch (IOException ex) { + return 0; + } + length = 0; + } + + // JEITA CP-3451 Exif Version 2.2 + if (length > 8) { + int offset = 0; + byte[] jpeg = new byte[length]; + if (!read(is, jpeg, length)) { + return 0; + } + + // Identify the byte order. + int tag = pack(jpeg, offset, 4, false); + if (tag != 0x49492A00 && tag != 0x4D4D002A) { + Log.e(TAG, "Invalid byte order"); + return 0; + } + boolean littleEndian = (tag == 0x49492A00); + + // Get the offset and check if it is reasonable. + int count = pack(jpeg, offset + 4, 4, littleEndian) + 2; + if (count < 10 || count > length) { + Log.e(TAG, "Invalid offset"); + return 0; + } + offset += count; + length -= count; + + // Get the count and go through all the elements. + count = pack(jpeg, offset - 2, 2, littleEndian); + while (count-- > 0 && length >= 12) { + // Get the tag and check if it is orientation. + tag = pack(jpeg, offset, 2, littleEndian); + if (tag == 0x0112) { + // We do not really care about type and count, do we? + int orientation = pack(jpeg, offset + 8, 2, littleEndian); + switch (orientation) { + case 1: + return 0; + case 3: + return 180; + case 6: + return 90; + case 8: + return 270; + } + Log.i(TAG, "Unsupported orientation"); + return 0; + } + offset += 12; + length -= 12; + } + } + + Log.i(TAG, "Orientation not found"); + return 0; + } + + private static int pack(byte[] bytes, int offset, int length, + boolean littleEndian) { + int step = 1; + if (littleEndian) { + offset += length - 1; + step = -1; + } + + int value = 0; + while (length-- > 0) { + value = (value << 8) | (bytes[offset] & 0xFF); + offset += step; + } + return value; + } + + private static boolean read(InputStream is, byte[] buf, int length) { + try { + return is.read(buf, 0, length) == length; + } catch (IOException ex) { + return false; + } + } +} diff --git a/src/eu/siacs/conversations/utils/PhoneHelper.java b/src/eu/siacs/conversations/utils/PhoneHelper.java index 25cff099..5becc7e7 100644 --- a/src/eu/siacs/conversations/utils/PhoneHelper.java +++ b/src/eu/siacs/conversations/utils/PhoneHelper.java @@ -22,7 +22,7 @@ public class PhoneHelper { final String[] PROJECTION = new String[] { ContactsContract.Data._ID, ContactsContract.Data.DISPLAY_NAME, - ContactsContract.Data.PHOTO_THUMBNAIL_URI, + ContactsContract.Data.PHOTO_URI, ContactsContract.Data.LOOKUP_KEY, ContactsContract.CommonDataKinds.Im.DATA }; @@ -50,10 +50,8 @@ public class PhoneHelper { "displayname", cursor.getString(cursor .getColumnIndex(ContactsContract.Data.DISPLAY_NAME))); - contact.putString( - "photouri", - cursor.getString(cursor - .getColumnIndex(ContactsContract.Data.PHOTO_THUMBNAIL_URI))); + contact.putString("photouri", cursor.getString(cursor + .getColumnIndex(ContactsContract.Data.PHOTO_URI))); contact.putString("lookup", cursor.getString(cursor .getColumnIndex(ContactsContract.Data.LOOKUP_KEY))); diff --git a/src/eu/siacs/conversations/utils/UIHelper.java b/src/eu/siacs/conversations/utils/UIHelper.java index 671e66d5..5141c83c 100644 --- a/src/eu/siacs/conversations/utils/UIHelper.java +++ b/src/eu/siacs/conversations/utils/UIHelper.java @@ -1,22 +1,18 @@ package eu.siacs.conversations.utils; -import java.io.FileNotFoundException; import java.util.ArrayList; import java.util.Calendar; import java.util.Date; import java.util.List; -import java.util.Locale; import java.util.regex.Pattern; import eu.siacs.conversations.R; import eu.siacs.conversations.entities.Account; import eu.siacs.conversations.entities.Contact; import eu.siacs.conversations.entities.Conversation; -import eu.siacs.conversations.entities.MucOptions.User; import eu.siacs.conversations.ui.ConversationActivity; import eu.siacs.conversations.ui.ManageAccountActivity; import android.annotation.SuppressLint; -import android.app.Activity; import android.app.AlertDialog; import android.app.Notification; import android.app.NotificationManager; @@ -25,28 +21,15 @@ import android.content.Context; import android.content.DialogInterface; import android.content.DialogInterface.OnClickListener; import android.content.Intent; -import android.graphics.Bitmap; -import android.graphics.BitmapFactory; -import android.graphics.Canvas; -import android.graphics.Paint; -import android.graphics.Rect; -import android.graphics.Typeface; -import android.net.Uri; -import android.provider.ContactsContract.Contacts; import android.support.v4.app.NotificationCompat; import android.support.v4.app.TaskStackBuilder; import android.text.format.DateFormat; import android.text.format.DateUtils; -import android.util.DisplayMetrics; import android.view.LayoutInflater; import android.view.View; -import android.widget.QuickContactBadge; import android.widget.TextView; public class UIHelper { - private static final int BG_COLOR = 0xFF181818; - private static final int FG_COLOR = 0xFFFAFAFA; - private static final int TRANSPARENT = 0x00000000; private static final int SHORT_DATE_FLAGS = DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_NO_YEAR | DateUtils.FORMAT_ABBREV_ALL; private static final int FULL_DATE_FLAGS = DateUtils.FORMAT_SHOW_TIME @@ -123,167 +106,6 @@ public class UIHelper { } } - public static int getRealPx(int dp, Context context) { - final DisplayMetrics metrics = context.getResources() - .getDisplayMetrics(); - return ((int) (dp * metrics.density)); - } - - private static int getNameColor(String name) { - /* - * int holoColors[] = { 0xFF1da9da, 0xFFb368d9, 0xFF83b600, 0xFFffa713, - * 0xFFe92727 }; - */ - int holoColors[] = { 0xFFe91e63, 0xFF9c27b0, 0xFF673ab7, 0xFF3f51b5, - 0xFF5677fc, 0xFF03a9f4, 0xFF00bcd4, 0xFF009688, 0xFFff5722, - 0xFF795548, 0xFF607d8b }; - return holoColors[(int) ((name.hashCode() & 0xffffffffl) % holoColors.length)]; - } - - private static void drawTile(Canvas canvas, String letter, int tileColor, - int textColor, int left, int top, int right, int bottom) { - Paint tilePaint = new Paint(), textPaint = new Paint(); - tilePaint.setColor(tileColor); - textPaint.setFlags(Paint.ANTI_ALIAS_FLAG); - textPaint.setColor(textColor); - textPaint.setTypeface(Typeface.create("sans-serif-light", - Typeface.NORMAL)); - textPaint.setTextSize((float) ((right - left) * 0.8)); - Rect rect = new Rect(); - - canvas.drawRect(new Rect(left, top, right, bottom), tilePaint); - textPaint.getTextBounds(letter, 0, 1, rect); - float width = textPaint.measureText(letter); - canvas.drawText(letter, (right + left) / 2 - width / 2, (top + bottom) - / 2 + rect.height() / 2, textPaint); - } - - private static Bitmap getUnknownContactPicture(String[] names, int size, - int bgColor, int fgColor) { - int tiles = (names.length > 4) ? 4 : (names.length < 1) ? 1 - : names.length; - Bitmap bitmap = Bitmap - .createBitmap(size, size, Bitmap.Config.ARGB_8888); - Canvas canvas = new Canvas(bitmap); - - String[] letters = new String[tiles]; - int[] colors = new int[tiles]; - if (names.length < 1) { - letters[0] = "?"; - colors[0] = 0xFFe92727; - } else { - for (int i = 0; i < tiles; ++i) { - letters[i] = (names[i].length() > 0) ? names[i].substring(0, 1) - .toUpperCase(Locale.US) : " "; - colors[i] = getNameColor(names[i]); - } - - if (names.length > 4) { - letters[3] = "\u2026"; // Unicode ellipsis - colors[3] = 0xFF202020; - } - } - - bitmap.eraseColor(bgColor); - - switch (tiles) { - case 1: - drawTile(canvas, letters[0], colors[0], fgColor, 0, 0, size, size); - break; - - case 2: - drawTile(canvas, letters[0], colors[0], fgColor, 0, 0, - size / 2 - 1, size); - drawTile(canvas, letters[1], colors[1], fgColor, size / 2 + 1, 0, - size, size); - break; - - case 3: - drawTile(canvas, letters[0], colors[0], fgColor, 0, 0, - size / 2 - 1, size); - drawTile(canvas, letters[1], colors[1], fgColor, size / 2 + 1, 0, - size, size / 2 - 1); - drawTile(canvas, letters[2], colors[2], fgColor, size / 2 + 1, - size / 2 + 1, size, size); - break; - - case 4: - drawTile(canvas, letters[0], colors[0], fgColor, 0, 0, - size / 2 - 1, size / 2 - 1); - drawTile(canvas, letters[1], colors[1], fgColor, 0, size / 2 + 1, - size / 2 - 1, size); - drawTile(canvas, letters[2], colors[2], fgColor, size / 2 + 1, 0, - size, size / 2 - 1); - drawTile(canvas, letters[3], colors[3], fgColor, size / 2 + 1, - size / 2 + 1, size, size); - break; - } - - return bitmap; - } - - private static Bitmap getMucContactPicture(Conversation conversation, - int size, int bgColor, int fgColor) { - List<User> members = conversation.getMucOptions().getUsers(); - if (members.size() == 0) { - return getUnknownContactPicture( - new String[] { conversation.getName() }, size, bgColor, - fgColor); - } - ArrayList<String> names = new ArrayList<String>(); - names.add(conversation.getMucOptions().getActualNick()); - for (User user : members) { - names.add(user.getName()); - if (names.size() > 4) { - break; - } - } - String[] mArrayNames = new String[names.size()]; - names.toArray(mArrayNames); - return getUnknownContactPicture(mArrayNames, size, bgColor, fgColor); - } - - public static Bitmap getContactPicture(Conversation conversation, - int dpSize, Context context, boolean notification) { - if (conversation.getMode() == Conversation.MODE_SINGLE) { - return getContactPicture(conversation.getContact(), dpSize, - context, notification); - } else { - int fgColor = UIHelper.FG_COLOR, bgColor = (notification) ? UIHelper.BG_COLOR - : UIHelper.TRANSPARENT; - - return getMucContactPicture(conversation, - getRealPx(dpSize, context), bgColor, fgColor); - } - } - - public static Bitmap getContactPicture(Contact contact, int dpSize, - Context context, boolean notification) { - String uri = contact.getProfilePhoto(); - if (uri == null) { - return getContactPicture(contact.getDisplayName(), dpSize, context, - notification); - } - try { - Bitmap bm = BitmapFactory.decodeStream(context.getContentResolver() - .openInputStream(Uri.parse(uri))); - return Bitmap.createScaledBitmap(bm, getRealPx(dpSize, context), - getRealPx(dpSize, context), false); - } catch (FileNotFoundException e) { - return getContactPicture(contact.getDisplayName(), dpSize, context, - notification); - } - } - - public static Bitmap getContactPicture(String name, int dpSize, - Context context, boolean notification) { - int fgColor = UIHelper.FG_COLOR, bgColor = (notification) ? UIHelper.BG_COLOR - : UIHelper.TRANSPARENT; - - return getUnknownContactPicture(new String[] { name }, - getRealPx(dpSize, context), bgColor, fgColor); - } - public static void showErrorNotification(Context context, List<Account> accounts) { NotificationManager mNotificationManager = (NotificationManager) context @@ -326,16 +148,6 @@ public class UIHelper { mNotificationManager.notify(1111, notification); } - public static void prepareContactBadge(final Activity activity, - QuickContactBadge badge, final Contact contact, Context context) { - if (contact.getSystemAccount() != null) { - String[] systemAccount = contact.getSystemAccount().split("#"); - long id = Long.parseLong(systemAccount[0]); - badge.assignContactUri(Contacts.getLookupUri(id, systemAccount[1])); - } - badge.setImageBitmap(contact.getImage(72, context)); - } - @SuppressLint("InflateParams") public static AlertDialog getVerifyFingerprintDialog( final ConversationActivity activity, @@ -370,25 +182,6 @@ public class UIHelper { return builder.create(); } - public static Bitmap getSelfContactPicture(Account account, int size, - boolean showPhoneSelfContactPicture, Context context) { - if (showPhoneSelfContactPicture) { - Uri selfiUri = PhoneHelper.getSefliUri(context); - if (selfiUri != null) { - try { - return BitmapFactory.decodeStream(context - .getContentResolver().openInputStream(selfiUri)); - } catch (FileNotFoundException e) { - return getContactPicture(account.getJid(), size, context, - false); - } - } - return getContactPicture(account.getJid(), size, context, false); - } else { - return getContactPicture(account.getJid(), size, context, false); - } - } - private final static class EmoticonPattern { Pattern pattern; String replacement; |