Device.java revision a9f1631fb83200a59e40e23ed366f810d08b6f52
13a5c1fb274a9ce72d708d88509bf2607cb018dddMarc Blank/* 23a5c1fb274a9ce72d708d88509bf2607cb018dddMarc Blank /* 33a5c1fb274a9ce72d708d88509bf2607cb018dddMarc Blank * Copyright (C) 2011 The Android Open Source Project 43a5c1fb274a9ce72d708d88509bf2607cb018dddMarc Blank * 53a5c1fb274a9ce72d708d88509bf2607cb018dddMarc Blank * Licensed under the Apache License, Version 2.0 (the "License"); 63a5c1fb274a9ce72d708d88509bf2607cb018dddMarc Blank * you may not use this file except in compliance with the License. 73a5c1fb274a9ce72d708d88509bf2607cb018dddMarc Blank * You may obtain a copy of the License at 83a5c1fb274a9ce72d708d88509bf2607cb018dddMarc Blank * 93a5c1fb274a9ce72d708d88509bf2607cb018dddMarc Blank * http://www.apache.org/licenses/LICENSE-2.0 103a5c1fb274a9ce72d708d88509bf2607cb018dddMarc Blank * 113a5c1fb274a9ce72d708d88509bf2607cb018dddMarc Blank * Unless required by applicable law or agreed to in writing, software 123a5c1fb274a9ce72d708d88509bf2607cb018dddMarc Blank * distributed under the License is distributed on an "AS IS" BASIS, 133a5c1fb274a9ce72d708d88509bf2607cb018dddMarc Blank * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 143a5c1fb274a9ce72d708d88509bf2607cb018dddMarc Blank * See the License for the specific language governing permissions and 153a5c1fb274a9ce72d708d88509bf2607cb018dddMarc Blank * limitations under the License. 163a5c1fb274a9ce72d708d88509bf2607cb018dddMarc Blank */ 173a5c1fb274a9ce72d708d88509bf2607cb018dddMarc Blank 183a5c1fb274a9ce72d708d88509bf2607cb018dddMarc Blankpackage com.android.emailcommon; 193a5c1fb274a9ce72d708d88509bf2607cb018dddMarc Blank 203a5c1fb274a9ce72d708d88509bf2607cb018dddMarc Blankimport android.content.Context; 213a5c1fb274a9ce72d708d88509bf2607cb018dddMarc Blankimport android.telephony.TelephonyManager; 223a5c1fb274a9ce72d708d88509bf2607cb018dddMarc Blankimport android.util.Log; 233a5c1fb274a9ce72d708d88509bf2607cb018dddMarc Blank 24a9f1631fb83200a59e40e23ed366f810d08b6f52Marc Blankimport com.android.emailcommon.utility.Utility; 25a9f1631fb83200a59e40e23ed366f810d08b6f52Marc Blank 263a5c1fb274a9ce72d708d88509bf2607cb018dddMarc Blankimport java.io.BufferedReader; 273a5c1fb274a9ce72d708d88509bf2607cb018dddMarc Blankimport java.io.BufferedWriter; 283a5c1fb274a9ce72d708d88509bf2607cb018dddMarc Blankimport java.io.File; 293a5c1fb274a9ce72d708d88509bf2607cb018dddMarc Blankimport java.io.FileReader; 303a5c1fb274a9ce72d708d88509bf2607cb018dddMarc Blankimport java.io.FileWriter; 313a5c1fb274a9ce72d708d88509bf2607cb018dddMarc Blankimport java.io.IOException; 323a5c1fb274a9ce72d708d88509bf2607cb018dddMarc Blank 333a5c1fb274a9ce72d708d88509bf2607cb018dddMarc Blankpublic class Device { 343a5c1fb274a9ce72d708d88509bf2607cb018dddMarc Blank private static String sDeviceId = null; 353a5c1fb274a9ce72d708d88509bf2607cb018dddMarc Blank 363a5c1fb274a9ce72d708d88509bf2607cb018dddMarc Blank /** 373a5c1fb274a9ce72d708d88509bf2607cb018dddMarc Blank * EAS requires a unique device id, so that sync is possible from a variety of different 383a5c1fb274a9ce72d708d88509bf2607cb018dddMarc Blank * devices (e.g. the syncKey is specific to a device) If we're on an emulator or some other 393a5c1fb274a9ce72d708d88509bf2607cb018dddMarc Blank * device that doesn't provide one, we can create it as android<n> where <n> is system time. 403a5c1fb274a9ce72d708d88509bf2607cb018dddMarc Blank * This would work on a real device as well, but it would be better to use the "real" id if 413a5c1fb274a9ce72d708d88509bf2607cb018dddMarc Blank * it's available 423a5c1fb274a9ce72d708d88509bf2607cb018dddMarc Blank */ 433a5c1fb274a9ce72d708d88509bf2607cb018dddMarc Blank static public synchronized String getDeviceId(Context context) throws IOException { 443a5c1fb274a9ce72d708d88509bf2607cb018dddMarc Blank if (sDeviceId == null) { 453a5c1fb274a9ce72d708d88509bf2607cb018dddMarc Blank sDeviceId = getDeviceIdInternal(context); 463a5c1fb274a9ce72d708d88509bf2607cb018dddMarc Blank } 473a5c1fb274a9ce72d708d88509bf2607cb018dddMarc Blank return sDeviceId; 483a5c1fb274a9ce72d708d88509bf2607cb018dddMarc Blank } 493a5c1fb274a9ce72d708d88509bf2607cb018dddMarc Blank 503a5c1fb274a9ce72d708d88509bf2607cb018dddMarc Blank static private String getDeviceIdInternal(Context context) throws IOException { 513a5c1fb274a9ce72d708d88509bf2607cb018dddMarc Blank if (context == null) { 523a5c1fb274a9ce72d708d88509bf2607cb018dddMarc Blank throw new IllegalStateException("getDeviceId requires a Context"); 533a5c1fb274a9ce72d708d88509bf2607cb018dddMarc Blank } 543a5c1fb274a9ce72d708d88509bf2607cb018dddMarc Blank File f = context.getFileStreamPath("deviceName"); 553a5c1fb274a9ce72d708d88509bf2607cb018dddMarc Blank BufferedReader rdr = null; 563a5c1fb274a9ce72d708d88509bf2607cb018dddMarc Blank String id; 573a5c1fb274a9ce72d708d88509bf2607cb018dddMarc Blank if (f.exists()) { 583a5c1fb274a9ce72d708d88509bf2607cb018dddMarc Blank if (f.canRead()) { 593a5c1fb274a9ce72d708d88509bf2607cb018dddMarc Blank rdr = new BufferedReader(new FileReader(f), 128); 603a5c1fb274a9ce72d708d88509bf2607cb018dddMarc Blank id = rdr.readLine(); 613a5c1fb274a9ce72d708d88509bf2607cb018dddMarc Blank rdr.close(); 62a6de89e79ca51535f92e38cd7b87fdfe32425c77Marc Blank if (id == null) { 63a6de89e79ca51535f92e38cd7b87fdfe32425c77Marc Blank // It's very bad if we read a null device id; let's delete that file 64a6de89e79ca51535f92e38cd7b87fdfe32425c77Marc Blank if (!f.delete()) { 65a6de89e79ca51535f92e38cd7b87fdfe32425c77Marc Blank Log.e(Logging.LOG_TAG, "Can't delete null deviceName file; try overwrite."); 66a6de89e79ca51535f92e38cd7b87fdfe32425c77Marc Blank } 67a6de89e79ca51535f92e38cd7b87fdfe32425c77Marc Blank } 683a5c1fb274a9ce72d708d88509bf2607cb018dddMarc Blank } else { 693a5c1fb274a9ce72d708d88509bf2607cb018dddMarc Blank Log.w(Logging.LOG_TAG, f.getAbsolutePath() + ": File exists, but can't read?" + 703a5c1fb274a9ce72d708d88509bf2607cb018dddMarc Blank " Trying to remove."); 713a5c1fb274a9ce72d708d88509bf2607cb018dddMarc Blank if (!f.delete()) { 723a5c1fb274a9ce72d708d88509bf2607cb018dddMarc Blank Log.w(Logging.LOG_TAG, "Remove failed. Tring to overwrite."); 733a5c1fb274a9ce72d708d88509bf2607cb018dddMarc Blank } 743a5c1fb274a9ce72d708d88509bf2607cb018dddMarc Blank } 753a5c1fb274a9ce72d708d88509bf2607cb018dddMarc Blank } 763a5c1fb274a9ce72d708d88509bf2607cb018dddMarc Blank BufferedWriter w = new BufferedWriter(new FileWriter(f), 128); 773a5c1fb274a9ce72d708d88509bf2607cb018dddMarc Blank final String consistentDeviceId = getConsistentDeviceId(context); 783a5c1fb274a9ce72d708d88509bf2607cb018dddMarc Blank if (consistentDeviceId != null) { 793a5c1fb274a9ce72d708d88509bf2607cb018dddMarc Blank // Use different prefix from random IDs. 803a5c1fb274a9ce72d708d88509bf2607cb018dddMarc Blank id = "androidc" + consistentDeviceId; 813a5c1fb274a9ce72d708d88509bf2607cb018dddMarc Blank } else { 823a5c1fb274a9ce72d708d88509bf2607cb018dddMarc Blank id = "android" + System.currentTimeMillis(); 833a5c1fb274a9ce72d708d88509bf2607cb018dddMarc Blank } 843a5c1fb274a9ce72d708d88509bf2607cb018dddMarc Blank w.write(id); 853a5c1fb274a9ce72d708d88509bf2607cb018dddMarc Blank w.close(); 863a5c1fb274a9ce72d708d88509bf2607cb018dddMarc Blank return id; 873a5c1fb274a9ce72d708d88509bf2607cb018dddMarc Blank } 883a5c1fb274a9ce72d708d88509bf2607cb018dddMarc Blank 893a5c1fb274a9ce72d708d88509bf2607cb018dddMarc Blank /** 903a5c1fb274a9ce72d708d88509bf2607cb018dddMarc Blank * @return Device's unique ID if available. null if the device has no unique ID. 913a5c1fb274a9ce72d708d88509bf2607cb018dddMarc Blank */ 923a5c1fb274a9ce72d708d88509bf2607cb018dddMarc Blank public static String getConsistentDeviceId(Context context) { 933a5c1fb274a9ce72d708d88509bf2607cb018dddMarc Blank final String deviceId; 943a5c1fb274a9ce72d708d88509bf2607cb018dddMarc Blank try { 953a5c1fb274a9ce72d708d88509bf2607cb018dddMarc Blank TelephonyManager tm = 963a5c1fb274a9ce72d708d88509bf2607cb018dddMarc Blank (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); 973a5c1fb274a9ce72d708d88509bf2607cb018dddMarc Blank if (tm == null) { 983a5c1fb274a9ce72d708d88509bf2607cb018dddMarc Blank return null; 993a5c1fb274a9ce72d708d88509bf2607cb018dddMarc Blank } 1003a5c1fb274a9ce72d708d88509bf2607cb018dddMarc Blank deviceId = tm.getDeviceId(); 1013a5c1fb274a9ce72d708d88509bf2607cb018dddMarc Blank if (deviceId == null) { 1023a5c1fb274a9ce72d708d88509bf2607cb018dddMarc Blank return null; 1033a5c1fb274a9ce72d708d88509bf2607cb018dddMarc Blank } 1043a5c1fb274a9ce72d708d88509bf2607cb018dddMarc Blank } catch (Exception e) { 1053a5c1fb274a9ce72d708d88509bf2607cb018dddMarc Blank Log.d(Logging.LOG_TAG, "Error in TelephonyManager.getDeviceId(): " + e.getMessage()); 1063a5c1fb274a9ce72d708d88509bf2607cb018dddMarc Blank return null; 1073a5c1fb274a9ce72d708d88509bf2607cb018dddMarc Blank } 1083a5c1fb274a9ce72d708d88509bf2607cb018dddMarc Blank return Utility.getSmallHash(deviceId); 1093a5c1fb274a9ce72d708d88509bf2607cb018dddMarc Blank } 1103a5c1fb274a9ce72d708d88509bf2607cb018dddMarc Blank} 111