Utility.java revision eb7752bf695b2a93854e0bb89ddbbc2236bb9aea
196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project/* 296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project 396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * 496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * you may not use this file except in compliance with the License. 696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * You may obtain a copy of the License at 796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * 896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * 1096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 1196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 1296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * See the License for the specific language governing permissions and 1496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * limitations under the License. 1596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project */ 1696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project 1796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Projectpackage com.android.email; 1896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project 19e1f0b0a9bcc78ade7f3b2ac540705701f19cd6cdAndrew Stadlerimport com.android.email.provider.EmailContent; 20da8836a76cd8a6eaa7e3693eeacc6393870b2066Andrew Stadlerimport com.android.email.provider.EmailContent.Account; 21da8836a76cd8a6eaa7e3693eeacc6393870b2066Andrew Stadlerimport com.android.email.provider.EmailContent.AccountColumns; 22da8836a76cd8a6eaa7e3693eeacc6393870b2066Andrew Stadlerimport com.android.email.provider.EmailContent.HostAuth; 23da8836a76cd8a6eaa7e3693eeacc6393870b2066Andrew Stadlerimport com.android.email.provider.EmailContent.HostAuthColumns; 24e1f0b0a9bcc78ade7f3b2ac540705701f19cd6cdAndrew Stadlerimport com.android.email.provider.EmailContent.Mailbox; 25e1f0b0a9bcc78ade7f3b2ac540705701f19cd6cdAndrew Stadlerimport com.android.email.provider.EmailContent.MailboxColumns; 26e1f0b0a9bcc78ade7f3b2ac540705701f19cd6cdAndrew Stadlerimport com.android.email.provider.EmailContent.Message; 27e1f0b0a9bcc78ade7f3b2ac540705701f19cd6cdAndrew Stadlerimport com.android.email.provider.EmailContent.MessageColumns; 28e1f0b0a9bcc78ade7f3b2ac540705701f19cd6cdAndrew Stadler 29e1f0b0a9bcc78ade7f3b2ac540705701f19cd6cdAndrew Stadlerimport android.content.ContentResolver; 30e1f0b0a9bcc78ade7f3b2ac540705701f19cd6cdAndrew Stadlerimport android.database.Cursor; 31e1f0b0a9bcc78ade7f3b2ac540705701f19cd6cdAndrew Stadler 3296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Projectimport java.io.IOException; 3396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Projectimport java.io.InputStream; 3496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Projectimport java.io.InputStreamReader; 3596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Projectimport java.io.UnsupportedEncodingException; 3696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Projectimport java.util.Date; 3796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project 3896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Projectimport com.android.email.codec.binary.Base64; 3996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project 40dadba9949895696108b31124fc0c6aa1a297ab1csatokimport android.content.Context; 41dadba9949895696108b31124fc0c6aa1a297ab1csatokimport android.content.res.TypedArray; 42dadba9949895696108b31124fc0c6aa1a297ab1csatokimport android.graphics.drawable.Drawable; 4396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Projectimport android.text.Editable; 4496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Projectimport android.widget.TextView; 4596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project 4696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Projectpublic class Utility { 4796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project public final static String readInputStream(InputStream in, String encoding) throws IOException { 4896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project InputStreamReader reader = new InputStreamReader(in, encoding); 4996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project StringBuffer sb = new StringBuffer(); 5096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project int count; 5196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project char[] buf = new char[512]; 5296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project while ((count = reader.read(buf)) != -1) { 5396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project sb.append(buf, 0, count); 5496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project } 5596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project return sb.toString(); 5696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project } 5796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project 5896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project public final static boolean arrayContains(Object[] a, Object o) { 5996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project for (int i = 0, count = a.length; i < count; i++) { 6096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project if (a[i].equals(o)) { 6196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project return true; 6296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project } 6396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project } 6496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project return false; 6596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project } 6696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project 6796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project /** 6896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * Combines the given array of Objects into a single string using the 6996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * seperator character and each Object's toString() method. between each 7096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * part. 7196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * 7296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * @param parts 7396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * @param seperator 7496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * @return 7596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project */ 7696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project public static String combine(Object[] parts, char seperator) { 7796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project if (parts == null) { 7896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project return null; 7996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project } 8096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project StringBuffer sb = new StringBuffer(); 8196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project for (int i = 0; i < parts.length; i++) { 8296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project sb.append(parts[i].toString()); 8396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project if (i < parts.length - 1) { 8496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project sb.append(seperator); 8596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project } 8696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project } 8796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project return sb.toString(); 8896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project } 8996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project 9096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project public static String base64Decode(String encoded) { 9196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project if (encoded == null) { 9296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project return null; 9396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project } 9496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project byte[] decoded = new Base64().decode(encoded.getBytes()); 9596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project return new String(decoded); 9696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project } 9796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project 9896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project public static String base64Encode(String s) { 9996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project if (s == null) { 10096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project return s; 10196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project } 10296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project byte[] encoded = new Base64().encode(s.getBytes()); 10396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project return new String(encoded); 10496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project } 10596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project 10696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project public static boolean requiredFieldValid(TextView view) { 10796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project return view.getText() != null && view.getText().length() > 0; 10896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project } 10996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project 11096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project public static boolean requiredFieldValid(Editable s) { 11196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project return s != null && s.length() > 0; 11296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project } 11396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project 11496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project /** 11596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * Ensures that the given string starts and ends with the double quote character. The string is not modified in any way except to add the 11696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * double quote character to start and end if it's not already there. 11796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * 11896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * TODO: Rename this, because "quoteString()" can mean so many different things. 11996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * 12096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * sample -> "sample" 12196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * "sample" -> "sample" 12296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * ""sample"" -> "sample" 12396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * "sample"" -> "sample" 12496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * sa"mp"le -> "sa"mp"le" 12596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * "sa"mp"le" -> "sa"mp"le" 12696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * (empty string) -> "" 12796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * " -> "" 12896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * @param s 12996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * @return 13096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project */ 13196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project public static String quoteString(String s) { 13296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project if (s == null) { 13396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project return null; 13496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project } 13596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project if (!s.matches("^\".*\"$")) { 13696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project return "\"" + s + "\""; 13796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project } 13896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project else { 13996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project return s; 14096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project } 14196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project } 14296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project 14396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project /** 14496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * Apply quoting rules per IMAP RFC, 14596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * quoted = DQUOTE *QUOTED-CHAR DQUOTE 14696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * QUOTED-CHAR = <any TEXT-CHAR except quoted-specials> / "\" quoted-specials 14796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * quoted-specials = DQUOTE / "\" 14896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * 14996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * This is used primarily for IMAP login, but might be useful elsewhere. 15096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * 15196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * NOTE: Not very efficient - you may wish to preflight this, or perhaps it should check 15296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * for trouble chars before calling the replace functions. 15396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * 15496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * @param s The string to be quoted. 15596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * @return A copy of the string, having undergone quoting as described above 15696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project */ 15796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project public static String imapQuoted(String s) { 15896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project 15996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project // First, quote any backslashes by replacing \ with \\ 16096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project // regex Pattern: \\ (Java string const = \\\\) 16196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project // Substitute: \\\\ (Java string const = \\\\\\\\) 16296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project String result = s.replaceAll("\\\\", "\\\\\\\\"); 16396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project 16496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project // Then, quote any double-quotes by replacing " with \" 16596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project // regex Pattern: " (Java string const = \") 16696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project // Substitute: \\" (Java string const = \\\\\") 16796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project result = result.replaceAll("\"", "\\\\\""); 16896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project 16996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project // return string with quotes around it 17096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project return "\"" + result + "\""; 17196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project } 17296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project 17396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project /** 17496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * A fast version of URLDecoder.decode() that works only with UTF-8 and does only two 17596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * allocations. This version is around 3x as fast as the standard one and I'm using it 17696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * hundreds of times in places that slow down the UI, so it helps. 17796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project */ 17896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project public static String fastUrlDecode(String s) { 17996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project try { 18096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project byte[] bytes = s.getBytes("UTF-8"); 18196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project byte ch; 18296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project int length = 0; 18396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project for (int i = 0, count = bytes.length; i < count; i++) { 18496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project ch = bytes[i]; 18596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project if (ch == '%') { 18696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project int h = (bytes[i + 1] - '0'); 18796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project int l = (bytes[i + 2] - '0'); 18896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project if (h > 9) { 18996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project h -= 7; 19096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project } 19196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project if (l > 9) { 19296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project l -= 7; 19396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project } 19496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project bytes[length] = (byte) ((h << 4) | l); 19596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project i += 2; 19696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project } 19796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project else if (ch == '+') { 19896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project bytes[length] = ' '; 19996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project } 20096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project else { 20196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project bytes[length] = bytes[i]; 20296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project } 20396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project length++; 20496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project } 20596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project return new String(bytes, 0, length, "UTF-8"); 20696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project } 20796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project catch (UnsupportedEncodingException uee) { 20896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project return null; 20996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project } 21096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project } 21196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project 21296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project /** 21396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * Returns true if the specified date is within today. Returns false otherwise. 21496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * @param date 21596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * @return 21696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project */ 21796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project public static boolean isDateToday(Date date) { 21896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project // TODO But Calendar is so slowwwwwww.... 21996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project Date today = new Date(); 22096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project if (date.getYear() == today.getYear() && 22196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project date.getMonth() == today.getMonth() && 22296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project date.getDate() == today.getDate()) { 22396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project return true; 22496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project } 22596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project return false; 22696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project } 22796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project 22896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project /* 22996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * TODO disabled this method globally. It is used in all the settings screens but I just 23096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * noticed that an unrelated icon was dimmed. Android must share drawables internally. 23196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project */ 23296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project public static void setCompoundDrawablesAlpha(TextView view, int alpha) { 23396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project// Drawable[] drawables = view.getCompoundDrawables(); 23496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project// for (Drawable drawable : drawables) { 23596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project// if (drawable != null) { 23696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project// drawable.setAlpha(alpha); 23796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project// } 23896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project// } 23996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project } 240e1f0b0a9bcc78ade7f3b2ac540705701f19cd6cdAndrew Stadler 241e1f0b0a9bcc78ade7f3b2ac540705701f19cd6cdAndrew Stadler // TODO: unit test this 242e1f0b0a9bcc78ade7f3b2ac540705701f19cd6cdAndrew Stadler public static String buildMailboxIdSelection(ContentResolver resolver, long mailboxId) { 243e1f0b0a9bcc78ade7f3b2ac540705701f19cd6cdAndrew Stadler // Setup default selection & args, then add to it as necessary 244e1f0b0a9bcc78ade7f3b2ac540705701f19cd6cdAndrew Stadler StringBuilder selection = new StringBuilder( 2456c21942ec45f561d711b3d74ecca8e62afb735c4Andrew Stadler MessageColumns.FLAG_LOADED + " IN (" 2466c21942ec45f561d711b3d74ecca8e62afb735c4Andrew Stadler + Message.FLAG_LOADED_PARTIAL + "," + Message.FLAG_LOADED_COMPLETE 2476c21942ec45f561d711b3d74ecca8e62afb735c4Andrew Stadler + ") AND "); 248e1f0b0a9bcc78ade7f3b2ac540705701f19cd6cdAndrew Stadler if (mailboxId == Mailbox.QUERY_ALL_INBOXES 249e1f0b0a9bcc78ade7f3b2ac540705701f19cd6cdAndrew Stadler || mailboxId == Mailbox.QUERY_ALL_DRAFTS 250e1f0b0a9bcc78ade7f3b2ac540705701f19cd6cdAndrew Stadler || mailboxId == Mailbox.QUERY_ALL_OUTBOX) { 251e1f0b0a9bcc78ade7f3b2ac540705701f19cd6cdAndrew Stadler // query for all mailboxes of type INBOX, DRAFTS, or OUTBOX 252e1f0b0a9bcc78ade7f3b2ac540705701f19cd6cdAndrew Stadler int type; 253e1f0b0a9bcc78ade7f3b2ac540705701f19cd6cdAndrew Stadler if (mailboxId == Mailbox.QUERY_ALL_INBOXES) { 254e1f0b0a9bcc78ade7f3b2ac540705701f19cd6cdAndrew Stadler type = Mailbox.TYPE_INBOX; 255e1f0b0a9bcc78ade7f3b2ac540705701f19cd6cdAndrew Stadler } else if (mailboxId == Mailbox.QUERY_ALL_DRAFTS) { 256e1f0b0a9bcc78ade7f3b2ac540705701f19cd6cdAndrew Stadler type = Mailbox.TYPE_DRAFTS; 257e1f0b0a9bcc78ade7f3b2ac540705701f19cd6cdAndrew Stadler } else { 258e1f0b0a9bcc78ade7f3b2ac540705701f19cd6cdAndrew Stadler type = Mailbox.TYPE_OUTBOX; 259e1f0b0a9bcc78ade7f3b2ac540705701f19cd6cdAndrew Stadler } 260e1f0b0a9bcc78ade7f3b2ac540705701f19cd6cdAndrew Stadler StringBuilder inboxes = new StringBuilder(); 261e1f0b0a9bcc78ade7f3b2ac540705701f19cd6cdAndrew Stadler Cursor c = resolver.query(Mailbox.CONTENT_URI, 262e1f0b0a9bcc78ade7f3b2ac540705701f19cd6cdAndrew Stadler EmailContent.ID_PROJECTION, 263e1f0b0a9bcc78ade7f3b2ac540705701f19cd6cdAndrew Stadler MailboxColumns.TYPE + "=? AND " + MailboxColumns.FLAG_VISIBLE + "=1", 264e1f0b0a9bcc78ade7f3b2ac540705701f19cd6cdAndrew Stadler new String[] { Integer.toString(type) }, null); 265e1f0b0a9bcc78ade7f3b2ac540705701f19cd6cdAndrew Stadler // build an IN (mailboxId, ...) list 266e1f0b0a9bcc78ade7f3b2ac540705701f19cd6cdAndrew Stadler // TODO do this directly in the provider 267e1f0b0a9bcc78ade7f3b2ac540705701f19cd6cdAndrew Stadler while (c.moveToNext()) { 268e1f0b0a9bcc78ade7f3b2ac540705701f19cd6cdAndrew Stadler if (inboxes.length() != 0) { 269e1f0b0a9bcc78ade7f3b2ac540705701f19cd6cdAndrew Stadler inboxes.append(","); 270e1f0b0a9bcc78ade7f3b2ac540705701f19cd6cdAndrew Stadler } 271e1f0b0a9bcc78ade7f3b2ac540705701f19cd6cdAndrew Stadler inboxes.append(c.getLong(EmailContent.ID_PROJECTION_COLUMN)); 272e1f0b0a9bcc78ade7f3b2ac540705701f19cd6cdAndrew Stadler } 273e1f0b0a9bcc78ade7f3b2ac540705701f19cd6cdAndrew Stadler c.close(); 274e1f0b0a9bcc78ade7f3b2ac540705701f19cd6cdAndrew Stadler selection.append(MessageColumns.MAILBOX_KEY + " IN "); 275e1f0b0a9bcc78ade7f3b2ac540705701f19cd6cdAndrew Stadler selection.append("(").append(inboxes).append(")"); 276e1f0b0a9bcc78ade7f3b2ac540705701f19cd6cdAndrew Stadler } else if (mailboxId == Mailbox.QUERY_ALL_UNREAD) { 277e1f0b0a9bcc78ade7f3b2ac540705701f19cd6cdAndrew Stadler selection.append(Message.FLAG_READ + "=0"); 278e1f0b0a9bcc78ade7f3b2ac540705701f19cd6cdAndrew Stadler } else if (mailboxId == Mailbox.QUERY_ALL_FAVORITES) { 279e1f0b0a9bcc78ade7f3b2ac540705701f19cd6cdAndrew Stadler selection.append(Message.FLAG_FAVORITE + "=1"); 280e1f0b0a9bcc78ade7f3b2ac540705701f19cd6cdAndrew Stadler } else { 281e1f0b0a9bcc78ade7f3b2ac540705701f19cd6cdAndrew Stadler selection.append(MessageColumns.MAILBOX_KEY + "=" + mailboxId); 282e1f0b0a9bcc78ade7f3b2ac540705701f19cd6cdAndrew Stadler } 283e1f0b0a9bcc78ade7f3b2ac540705701f19cd6cdAndrew Stadler return selection.toString(); 284e1f0b0a9bcc78ade7f3b2ac540705701f19cd6cdAndrew Stadler } 285dadba9949895696108b31124fc0c6aa1a297ab1csatok 286dadba9949895696108b31124fc0c6aa1a297ab1csatok public static class FolderProperties { 287dadba9949895696108b31124fc0c6aa1a297ab1csatok 288dadba9949895696108b31124fc0c6aa1a297ab1csatok private static FolderProperties sInstance; 289dadba9949895696108b31124fc0c6aa1a297ab1csatok 290dadba9949895696108b31124fc0c6aa1a297ab1csatok // Caches for frequently accessed resources. 291dadba9949895696108b31124fc0c6aa1a297ab1csatok private String[] mSpecialMailbox = new String[] {}; 292dadba9949895696108b31124fc0c6aa1a297ab1csatok private TypedArray mSpecialMailboxDrawable; 293dadba9949895696108b31124fc0c6aa1a297ab1csatok private Drawable mDefaultMailboxDrawable; 2943786cab2aa1776e92fc67af3931a76cd8b848b48satok private Drawable mSummaryStarredMailboxDrawable; 2953786cab2aa1776e92fc67af3931a76cd8b848b48satok private Drawable mSummaryCombinedInboxDrawable; 296dadba9949895696108b31124fc0c6aa1a297ab1csatok 297dadba9949895696108b31124fc0c6aa1a297ab1csatok private FolderProperties(Context context) { 298fa52e6c95674aef6461a5cfc670a052e1c5b7f2fAndrew Stadler mSpecialMailbox = context.getResources().getStringArray(R.array.mailbox_display_names); 299dadba9949895696108b31124fc0c6aa1a297ab1csatok for (int i = 0; i < mSpecialMailbox.length; ++i) { 300dadba9949895696108b31124fc0c6aa1a297ab1csatok if ("".equals(mSpecialMailbox[i])) { 301dadba9949895696108b31124fc0c6aa1a297ab1csatok // there is no localized name, so use the display name from the server 302dadba9949895696108b31124fc0c6aa1a297ab1csatok mSpecialMailbox[i] = null; 303dadba9949895696108b31124fc0c6aa1a297ab1csatok } 304dadba9949895696108b31124fc0c6aa1a297ab1csatok } 305dadba9949895696108b31124fc0c6aa1a297ab1csatok mSpecialMailboxDrawable = 306fa52e6c95674aef6461a5cfc670a052e1c5b7f2fAndrew Stadler context.getResources().obtainTypedArray(R.array.mailbox_display_icons); 307dadba9949895696108b31124fc0c6aa1a297ab1csatok mDefaultMailboxDrawable = 308dadba9949895696108b31124fc0c6aa1a297ab1csatok context.getResources().getDrawable(R.drawable.ic_list_folder); 3093786cab2aa1776e92fc67af3931a76cd8b848b48satok mSummaryStarredMailboxDrawable = 3103786cab2aa1776e92fc67af3931a76cd8b848b48satok context.getResources().getDrawable(R.drawable.ic_list_starred); 3113786cab2aa1776e92fc67af3931a76cd8b848b48satok mSummaryCombinedInboxDrawable = 3123786cab2aa1776e92fc67af3931a76cd8b848b48satok context.getResources().getDrawable(R.drawable.ic_list_combined_inbox); 313dadba9949895696108b31124fc0c6aa1a297ab1csatok } 314dadba9949895696108b31124fc0c6aa1a297ab1csatok 315dadba9949895696108b31124fc0c6aa1a297ab1csatok public static FolderProperties getInstance(Context context) { 316dadba9949895696108b31124fc0c6aa1a297ab1csatok if (sInstance == null) { 317dadba9949895696108b31124fc0c6aa1a297ab1csatok synchronized (FolderProperties.class) { 318dadba9949895696108b31124fc0c6aa1a297ab1csatok if (sInstance == null) { 319dadba9949895696108b31124fc0c6aa1a297ab1csatok sInstance = new FolderProperties(context); 320dadba9949895696108b31124fc0c6aa1a297ab1csatok } 321dadba9949895696108b31124fc0c6aa1a297ab1csatok } 322dadba9949895696108b31124fc0c6aa1a297ab1csatok } 323dadba9949895696108b31124fc0c6aa1a297ab1csatok return sInstance; 324dadba9949895696108b31124fc0c6aa1a297ab1csatok } 325dadba9949895696108b31124fc0c6aa1a297ab1csatok 326dadba9949895696108b31124fc0c6aa1a297ab1csatok /** 327dadba9949895696108b31124fc0c6aa1a297ab1csatok * Lookup names of localized special mailboxes 328dadba9949895696108b31124fc0c6aa1a297ab1csatok * @param type 329dadba9949895696108b31124fc0c6aa1a297ab1csatok * @return Localized strings 330dadba9949895696108b31124fc0c6aa1a297ab1csatok */ 331dadba9949895696108b31124fc0c6aa1a297ab1csatok public String getDisplayName(int type) { 332dadba9949895696108b31124fc0c6aa1a297ab1csatok if (type < mSpecialMailbox.length) { 333dadba9949895696108b31124fc0c6aa1a297ab1csatok return mSpecialMailbox[type]; 334dadba9949895696108b31124fc0c6aa1a297ab1csatok } 335dadba9949895696108b31124fc0c6aa1a297ab1csatok return null; 336dadba9949895696108b31124fc0c6aa1a297ab1csatok } 337dadba9949895696108b31124fc0c6aa1a297ab1csatok 338dadba9949895696108b31124fc0c6aa1a297ab1csatok /** 339dadba9949895696108b31124fc0c6aa1a297ab1csatok * Lookup icons of special mailboxes 340dadba9949895696108b31124fc0c6aa1a297ab1csatok * @param type 341dadba9949895696108b31124fc0c6aa1a297ab1csatok * @return icon's drawable 342dadba9949895696108b31124fc0c6aa1a297ab1csatok */ 3434bb52e36b18ab5e2fb9242069611bc0ef6116c09satok public Drawable getIconIds(int type) { 344dadba9949895696108b31124fc0c6aa1a297ab1csatok if (type < mSpecialMailboxDrawable.length()) { 345dadba9949895696108b31124fc0c6aa1a297ab1csatok return mSpecialMailboxDrawable.getDrawable(type); 346dadba9949895696108b31124fc0c6aa1a297ab1csatok } 347dadba9949895696108b31124fc0c6aa1a297ab1csatok return mDefaultMailboxDrawable; 348dadba9949895696108b31124fc0c6aa1a297ab1csatok } 3493786cab2aa1776e92fc67af3931a76cd8b848b48satok 3503786cab2aa1776e92fc67af3931a76cd8b848b48satok public Drawable getSummaryMailboxIconIds(long mailboxKey) { 3513786cab2aa1776e92fc67af3931a76cd8b848b48satok if (mailboxKey == Mailbox.QUERY_ALL_INBOXES) { 3523786cab2aa1776e92fc67af3931a76cd8b848b48satok return mSummaryCombinedInboxDrawable; 3533786cab2aa1776e92fc67af3931a76cd8b848b48satok } else if (mailboxKey == Mailbox.QUERY_ALL_FAVORITES) { 3543786cab2aa1776e92fc67af3931a76cd8b848b48satok return mSummaryStarredMailboxDrawable; 3553786cab2aa1776e92fc67af3931a76cd8b848b48satok } else if (mailboxKey == Mailbox.QUERY_ALL_DRAFTS) { 3563786cab2aa1776e92fc67af3931a76cd8b848b48satok return mSpecialMailboxDrawable.getDrawable(Mailbox.TYPE_DRAFTS); 3573786cab2aa1776e92fc67af3931a76cd8b848b48satok } else if (mailboxKey == Mailbox.QUERY_ALL_OUTBOX) { 3583786cab2aa1776e92fc67af3931a76cd8b848b48satok return mSpecialMailboxDrawable.getDrawable(Mailbox.TYPE_OUTBOX); 3593786cab2aa1776e92fc67af3931a76cd8b848b48satok } 3603786cab2aa1776e92fc67af3931a76cd8b848b48satok return mDefaultMailboxDrawable; 3613786cab2aa1776e92fc67af3931a76cd8b848b48satok } 362dadba9949895696108b31124fc0c6aa1a297ab1csatok } 363da8836a76cd8a6eaa7e3693eeacc6393870b2066Andrew Stadler 364da8836a76cd8a6eaa7e3693eeacc6393870b2066Andrew Stadler private final static String HOSTAUTH_WHERE_CREDENTIALS = HostAuthColumns.ADDRESS + " like ?" 365da8836a76cd8a6eaa7e3693eeacc6393870b2066Andrew Stadler + " and " + HostAuthColumns.LOGIN + " like ?" 366da8836a76cd8a6eaa7e3693eeacc6393870b2066Andrew Stadler + " and " + HostAuthColumns.PROTOCOL + " not like \"smtp\""; 367da8836a76cd8a6eaa7e3693eeacc6393870b2066Andrew Stadler private final static String ACCOUNT_WHERE_HOSTAUTH = AccountColumns.HOST_AUTH_KEY_RECV + "=?"; 368da8836a76cd8a6eaa7e3693eeacc6393870b2066Andrew Stadler 369da8836a76cd8a6eaa7e3693eeacc6393870b2066Andrew Stadler /** 370da8836a76cd8a6eaa7e3693eeacc6393870b2066Andrew Stadler * Look for an existing account with the same username & server 371da8836a76cd8a6eaa7e3693eeacc6393870b2066Andrew Stadler * 372da8836a76cd8a6eaa7e3693eeacc6393870b2066Andrew Stadler * @param context a system context 373da8836a76cd8a6eaa7e3693eeacc6393870b2066Andrew Stadler * @param allowAccountId this account Id will not trigger (when editing an existing account) 374da8836a76cd8a6eaa7e3693eeacc6393870b2066Andrew Stadler * @param hostName the server 375da8836a76cd8a6eaa7e3693eeacc6393870b2066Andrew Stadler * @param userLogin the user login string 376da8836a76cd8a6eaa7e3693eeacc6393870b2066Andrew Stadler * @result null = no dupes found. non-null = dupe account's display name 377da8836a76cd8a6eaa7e3693eeacc6393870b2066Andrew Stadler */ 378da8836a76cd8a6eaa7e3693eeacc6393870b2066Andrew Stadler public static String findDuplicateAccount(Context context, long allowAccountId, String hostName, 379da8836a76cd8a6eaa7e3693eeacc6393870b2066Andrew Stadler String userLogin) { 380da8836a76cd8a6eaa7e3693eeacc6393870b2066Andrew Stadler ContentResolver resolver = context.getContentResolver(); 381da8836a76cd8a6eaa7e3693eeacc6393870b2066Andrew Stadler Cursor c = resolver.query(HostAuth.CONTENT_URI, HostAuth.ID_PROJECTION, 382da8836a76cd8a6eaa7e3693eeacc6393870b2066Andrew Stadler HOSTAUTH_WHERE_CREDENTIALS, new String[] { hostName, userLogin }, null); 383da8836a76cd8a6eaa7e3693eeacc6393870b2066Andrew Stadler try { 384da8836a76cd8a6eaa7e3693eeacc6393870b2066Andrew Stadler while (c.moveToNext()) { 385da8836a76cd8a6eaa7e3693eeacc6393870b2066Andrew Stadler long hostAuthId = c.getLong(HostAuth.ID_PROJECTION_COLUMN); 386da8836a76cd8a6eaa7e3693eeacc6393870b2066Andrew Stadler // Find account with matching hostauthrecv key, and return its display name 387da8836a76cd8a6eaa7e3693eeacc6393870b2066Andrew Stadler Cursor c2 = resolver.query(Account.CONTENT_URI, Account.ID_PROJECTION, 388da8836a76cd8a6eaa7e3693eeacc6393870b2066Andrew Stadler ACCOUNT_WHERE_HOSTAUTH, new String[] { Long.toString(hostAuthId) }, null); 389da8836a76cd8a6eaa7e3693eeacc6393870b2066Andrew Stadler try { 390da8836a76cd8a6eaa7e3693eeacc6393870b2066Andrew Stadler while (c2.moveToNext()) { 391da8836a76cd8a6eaa7e3693eeacc6393870b2066Andrew Stadler long accountId = c2.getLong(Account.ID_PROJECTION_COLUMN); 392da8836a76cd8a6eaa7e3693eeacc6393870b2066Andrew Stadler if (accountId != allowAccountId) { 393da8836a76cd8a6eaa7e3693eeacc6393870b2066Andrew Stadler Account account = Account.restoreAccountWithId(context, accountId); 394da8836a76cd8a6eaa7e3693eeacc6393870b2066Andrew Stadler if (account != null) { 395da8836a76cd8a6eaa7e3693eeacc6393870b2066Andrew Stadler return account.mDisplayName; 396da8836a76cd8a6eaa7e3693eeacc6393870b2066Andrew Stadler } 397da8836a76cd8a6eaa7e3693eeacc6393870b2066Andrew Stadler } 398da8836a76cd8a6eaa7e3693eeacc6393870b2066Andrew Stadler } 399da8836a76cd8a6eaa7e3693eeacc6393870b2066Andrew Stadler } finally { 400da8836a76cd8a6eaa7e3693eeacc6393870b2066Andrew Stadler c2.close(); 401da8836a76cd8a6eaa7e3693eeacc6393870b2066Andrew Stadler } 402da8836a76cd8a6eaa7e3693eeacc6393870b2066Andrew Stadler } 403da8836a76cd8a6eaa7e3693eeacc6393870b2066Andrew Stadler } finally { 404da8836a76cd8a6eaa7e3693eeacc6393870b2066Andrew Stadler c.close(); 405da8836a76cd8a6eaa7e3693eeacc6393870b2066Andrew Stadler } 406da8836a76cd8a6eaa7e3693eeacc6393870b2066Andrew Stadler 407da8836a76cd8a6eaa7e3693eeacc6393870b2066Andrew Stadler return null; 408da8836a76cd8a6eaa7e3693eeacc6393870b2066Andrew Stadler } 409eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler 410eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler /** 411eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler * Generate a random message-id header for locally-generated messages. 412eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler */ 413eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler public static String generateMessageId() { 414eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler StringBuffer sb = new StringBuffer(); 415eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler sb.append("<"); 416eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler for (int i = 0; i < 24; i++) { 417eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler sb.append(Integer.toString((int)(Math.random() * 35), 36)); 418eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler } 419eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler sb.append("."); 420eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler sb.append(Long.toString(System.currentTimeMillis())); 421eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler sb.append("@email.android.com>"); 422eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler return sb.toString(); 423eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler } 424eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler 42596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project} 426