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