Device.java revision a6de89e79ca51535f92e38cd7b87fdfe32425c77
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 18package com.android.emailcommon; 19 20import com.android.emailcommon.utility.Utility; 21 22import android.content.Context; 23import android.telephony.TelephonyManager; 24import android.util.Log; 25 26import java.io.BufferedReader; 27import java.io.BufferedWriter; 28import java.io.File; 29import java.io.FileReader; 30import java.io.FileWriter; 31import java.io.IOException; 32 33public 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 */ 43 static public synchronized String getDeviceId(Context context) throws IOException { 44 if (sDeviceId == null) { 45 sDeviceId = getDeviceIdInternal(context); 46 } 47 return sDeviceId; 48 } 49 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 Log.e(Logging.LOG_TAG, "Can't delete null deviceName file; try overwrite."); 66 } 67 } else { 68 // STOPSHIP Remove logging 69 Log.w(Logging.LOG_TAG, "deviceId read as: " + id); 70 return id; 71 } 72 } else { 73 Log.w(Logging.LOG_TAG, f.getAbsolutePath() + ": File exists, but can't read?" + 74 " Trying to remove."); 75 if (!f.delete()) { 76 Log.w(Logging.LOG_TAG, "Remove failed. Tring to overwrite."); 77 } 78 } 79 } 80 BufferedWriter w = new BufferedWriter(new FileWriter(f), 128); 81 final String consistentDeviceId = getConsistentDeviceId(context); 82 if (consistentDeviceId != null) { 83 // Use different prefix from random IDs. 84 id = "androidc" + consistentDeviceId; 85 } else { 86 id = "android" + System.currentTimeMillis(); 87 } 88 w.write(id); 89 w.close(); 90 // STOPSHIP Remove logging 91 Log.w(Logging.LOG_TAG, "deviceId written as: " + id); 92 return id; 93 } 94 95 /** 96 * @return Device's unique ID if available. null if the device has no unique ID. 97 */ 98 public static String getConsistentDeviceId(Context context) { 99 final String deviceId; 100 try { 101 TelephonyManager tm = 102 (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); 103 if (tm == null) { 104 return null; 105 } 106 deviceId = tm.getDeviceId(); 107 if (deviceId == null) { 108 return null; 109 } 110 } catch (Exception e) { 111 Log.d(Logging.LOG_TAG, "Error in TelephonyManager.getDeviceId(): " + e.getMessage()); 112 return null; 113 } 114 return Utility.getSmallHash(deviceId); 115 } 116} 117