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