forked from vieux/OpenUDID
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathOpenUDID_manager.java
196 lines (160 loc) · 6.08 KB
/
OpenUDID_manager.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
package org.OpenUDID;
import java.math.BigInteger;
import java.security.SecureRandom;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.TreeMap;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.os.IBinder;
import android.os.RemoteException;
import android.provider.Settings.Secure;
import android.util.Log;
public class OpenUDID_manager implements ServiceConnection{
public final static String PREF_KEY = "openudid";
public final static String PREFS_NAME = "openudid_prefs";
public final static String TAG = "OpenUDID";
private final static boolean LOG = true; //Display or not debug message
private final Context mContext; //Application context
private List<ResolveInfo> mMatchingIntents; //List of available OpenUDID Intents
private Map<String, Integer> mReceivedOpenUDIDs; //Map of OpenUDIDs found so far
private final SharedPreferences mPreferences; //Preferences to store the OpenUDID
private final Random mRandom;
private OpenUDID_manager(Context context) {
mPreferences = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
mContext = context;
mRandom = new Random();
mReceivedOpenUDIDs = new HashMap<String, Integer>();
}
@Override
public void onServiceConnected(ComponentName className, IBinder service) {
//Get the OpenUDID from the remote service
try {
//Send a random number to the service
android.os.Parcel data = android.os.Parcel.obtain();
data.writeInt(mRandom.nextInt());
android.os.Parcel reply = android.os.Parcel.obtain();
service.transact(1, android.os.Parcel.obtain(), reply, 0);
if (data.readInt() == reply.readInt()) //Check if the service returns us this number
{
final String _openUDID = reply.readString();
if (_openUDID != null) { //if valid OpenUDID, save it
if (LOG) Log.d(TAG, "Received " + _openUDID);
if (mReceivedOpenUDIDs.containsKey(_openUDID)) mReceivedOpenUDIDs.put(_openUDID, mReceivedOpenUDIDs.get(_openUDID) + 1);
else mReceivedOpenUDIDs.put(_openUDID, 1);
}
}
} catch (RemoteException e) {if (LOG) Log.e(TAG, "RemoteException: " + e.getMessage());}
mContext.unbindService(this);
startService(); //Try the next one
}
@Override
public void onServiceDisconnected(ComponentName className) {}
private void storeOpenUDID() {
final Editor e = mPreferences.edit();
e.putString(PREF_KEY, OpenUDID);
e.commit();
}
/*
* Generate a new OpenUDID
*/
private void generateOpenUDID() {
if (LOG) Log.d(TAG, "Generating openUDID");
//Try to get the ANDROID_ID
OpenUDID = Secure.getString(mContext.getContentResolver(), Secure.ANDROID_ID);
if (OpenUDID == null || OpenUDID.equals("9774d56d682e549c") || OpenUDID.length() < 15 ) {
//if ANDROID_ID is null, or it's equals to the GalaxyTab generic ANDROID_ID or bad, generates a new one
final SecureRandom random = new SecureRandom();
OpenUDID = new BigInteger(64, random).toString(16);
}
}
/*
* Start the oldest service
*/
private void startService() {
if (mMatchingIntents.size() > 0) { //There are some Intents untested
if (LOG) Log.d(TAG, "Trying service " + mMatchingIntents.get(0).loadLabel(mContext.getPackageManager()));
final ServiceInfo servInfo = mMatchingIntents.get(0).serviceInfo;
final Intent i = new Intent();
i.setComponent(new ComponentName(servInfo.applicationInfo.packageName, servInfo.name));
mContext.bindService(i, this, Context.BIND_AUTO_CREATE);
mMatchingIntents.remove(0);
} else { //No more service to test
getMostFrequentOpenUDID(); //Choose the most frequent
if (OpenUDID == null) //No OpenUDID was chosen, generate one
generateOpenUDID();
if (LOG) Log.d(TAG, "OpenUDID: " + OpenUDID);
storeOpenUDID();//Store it locally
mInitialized = true;
}
}
private void getMostFrequentOpenUDID() {
if (mReceivedOpenUDIDs.isEmpty() == false) {
final TreeMap<String,Integer> sorted_OpenUDIDS = new TreeMap(new ValueComparator());
sorted_OpenUDIDS.putAll(mReceivedOpenUDIDs);
OpenUDID = sorted_OpenUDIDS.firstKey();
}
}
private static String OpenUDID = null;
private static boolean mInitialized = false;
/**
* The Method to call to get OpenUDID
* @return the OpenUDID
*/
public static String getOpenUDID() {
if (!mInitialized) Log.e("OpenUDID", "Initialisation isn't done");
return OpenUDID;
}
/**
* The Method to call to get OpenUDID
* @return the OpenUDID
*/
public static boolean isInitialized() {
return mInitialized;
}
/**
* The Method the call at the init of your app
* @param context you current context
*/
public static void sync(Context context) {
//Initialise the Manager
OpenUDID_manager manager = new OpenUDID_manager(context);
//Try to get the openudid from local preferences
OpenUDID = manager.mPreferences.getString(PREF_KEY, null);
if (OpenUDID == null) //Not found
{
//Get the list of all OpenUDID services available (including itself)
manager.mMatchingIntents = context.getPackageManager().queryIntentServices(new Intent("org.OpenUDID.GETUDID"), 0);
if (LOG) Log.d(TAG, manager.mMatchingIntents.size() + " services matches OpenUDID");
if (manager.mMatchingIntents != null)
//Start services one by one
manager.startService();
} else {//Got it, you can now call getOpenUDID()
if (LOG) Log.d(TAG, "OpenUDID: " + OpenUDID);
mInitialized = true;
}
}
/*
* Used to sort the OpenUDIDs collected by occurrence
*/
private class ValueComparator implements Comparator {
public int compare(Object a, Object b) {
if(mReceivedOpenUDIDs.get(a) < mReceivedOpenUDIDs.get(b)) {
return 1;
} else if(mReceivedOpenUDIDs.get(a) == mReceivedOpenUDIDs.get(b)) {
return 0;
} else {
return -1;
}
}
}
}