1 /* 2 /* 3 * Copyright (C) 2011 The Android Open Source Project 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.emailcommon; 19 20 import android.content.Context; 21 import android.telephony.TelephonyManager; 22 23 import com.android.emailcommon.utility.Utility; 24 import com.android.mail.utils.LogUtils; 25 26 import java.io.BufferedReader; 27 import java.io.BufferedWriter; 28 import java.io.File; 29 import java.io.FileReader; 30 import java.io.FileWriter; 31 import java.io.IOException; 32 33 public class Device { 34 private static String sDeviceId = null; 35 36 /** 37 * EAS requires a unique device id, so that sync is possible from a variety of different 38 * devices (e.g. the syncKey is specific to a device) If we're on an emulator or some other 39 * device that doesn't provide one, we can create it as android<n> where <n> is system time. 40 * This would work on a real device as well, but it would be better to use the "real" id if 41 * it's available 42 */ getDeviceId(Context context)43 static public synchronized String getDeviceId(Context context) throws IOException { 44 if (sDeviceId == null) { 45 sDeviceId = getDeviceIdInternal(context); 46 } 47 return sDeviceId; 48 } 49 getDeviceIdInternal(Context context)50 static private String getDeviceIdInternal(Context context) throws IOException { 51 if (context == null) { 52 throw new IllegalStateException("getDeviceId requires a Context"); 53 } 54 File f = context.getFileStreamPath("deviceName"); 55 BufferedReader rdr = null; 56 String id; 57 if (f.exists()) { 58 if (f.canRead()) { 59 rdr = new BufferedReader(new FileReader(f), 128); 60 id = rdr.readLine(); 61 rdr.close(); 62 if (id == null) { 63 // It's very bad if we read a null device id; let's delete that file 64 if (!f.delete()) { 65 LogUtils.e(Logging.LOG_TAG, 66 "Can't delete null deviceName file; try overwrite."); 67 } 68 } else { 69 return id; 70 } 71 } else { 72 LogUtils.w(Logging.LOG_TAG, f.getAbsolutePath() + ": File exists, but can't read?" + 73 " Trying to remove."); 74 if (!f.delete()) { 75 LogUtils.w(Logging.LOG_TAG, "Remove failed. Tring to overwrite."); 76 } 77 } 78 } 79 BufferedWriter w = new BufferedWriter(new FileWriter(f), 128); 80 final String consistentDeviceId = getConsistentDeviceId(context); 81 if (consistentDeviceId != null) { 82 // Use different prefix from random IDs. 83 id = "androidc" + consistentDeviceId; 84 } else { 85 id = "android" + System.currentTimeMillis(); 86 } 87 w.write(id); 88 w.close(); 89 return id; 90 } 91 92 /** 93 * @return Device's unique ID if available. null if the device has no unique ID. 94 */ getConsistentDeviceId(Context context)95 public static String getConsistentDeviceId(Context context) { 96 final String deviceId; 97 try { 98 TelephonyManager tm = 99 (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); 100 if (tm == null) { 101 return null; 102 } 103 deviceId = tm.getDeviceId(); 104 if (deviceId == null) { 105 return null; 106 } 107 } catch (Exception e) { 108 LogUtils.d(Logging.LOG_TAG, "Error in TelephonyManager.getDeviceId(): " 109 + e.getMessage()); 110 return null; 111 } 112 return Utility.getSmallHash(deviceId); 113 } 114 } 115