Skip to content

Commit af45ea5

Browse files
Jeasminejkasten2
authored andcommitted
Create GMS and HMS Loction controller
* Separate location controller by platform
1 parent b2af407 commit af45ea5

14 files changed

+452
-308
lines changed
Lines changed: 208 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,208 @@
1+
/**
2+
* Modified MIT License
3+
* <p>
4+
* Copyright 2020 OneSignal
5+
* <p>
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
* <p>
13+
* 1. The above copyright notice and this permission notice shall be included in
14+
* all copies or substantial portions of the Software.
15+
* <p>
16+
* 2. All copies of substantial portions of the Software may only be used in connection
17+
* with services provided by OneSignal.
18+
* <p>
19+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25+
* THE SOFTWARE.
26+
*/
27+
28+
package com.onesignal;
29+
30+
import android.location.Location;
31+
import android.os.Bundle;
32+
import android.support.annotation.NonNull;
33+
34+
import com.google.android.gms.common.ConnectionResult;
35+
import com.google.android.gms.common.api.GoogleApiClient;
36+
import com.google.android.gms.location.LocationListener;
37+
import com.google.android.gms.location.LocationRequest;
38+
import com.google.android.gms.location.LocationServices;
39+
40+
class GMSLocationController extends LocationController {
41+
42+
static final int API_FALLBACK_TIME = 30_000;
43+
44+
private static GoogleApiClientCompatProxy googleApiClient;
45+
static LocationUpdateListener locationUpdateListener;
46+
47+
// Started from this class or PermissionActivity
48+
static void startGetLocation() {
49+
initGoogleLocation();
50+
}
51+
52+
private static void initGoogleLocation() {
53+
// Prevents overlapping requests
54+
if (fallbackFailThread != null)
55+
return;
56+
57+
synchronized (syncLock) {
58+
startFallBackThread();
59+
60+
if (googleApiClient == null || lastLocation == null) {
61+
GoogleApiClientListener googleApiClientListener = new GoogleApiClientListener();
62+
GoogleApiClient googleApiClient = new GoogleApiClient.Builder(classContext)
63+
.addApi(LocationServices.API)
64+
.addConnectionCallbacks(googleApiClientListener)
65+
.addOnConnectionFailedListener(googleApiClientListener)
66+
.setHandler(locationHandlerThread.mHandler)
67+
.build();
68+
69+
GMSLocationController.googleApiClient = new GoogleApiClientCompatProxy(googleApiClient);
70+
GMSLocationController.googleApiClient.connect();
71+
} else if (lastLocation != null)
72+
fireCompleteForLocation(lastLocation);
73+
}
74+
}
75+
76+
private static int getApiFallbackWait() {
77+
return API_FALLBACK_TIME;
78+
}
79+
80+
private static void startFallBackThread() {
81+
fallbackFailThread = new Thread(new Runnable() {
82+
public void run() {
83+
try {
84+
Thread.sleep(getApiFallbackWait());
85+
OneSignal.Log(OneSignal.LOG_LEVEL.WARN, "Location permission exists but GoogleApiClient timed out. Maybe related to mismatch google-play aar versions.");
86+
LocationController.fireFailedComplete();
87+
scheduleUpdate(classContext);
88+
} catch (InterruptedException e) {
89+
// Interruptions expected when connection is made to the api
90+
}
91+
}
92+
}, "OS_GMS_LOCATION_FALLBACK");
93+
fallbackFailThread.start();
94+
}
95+
96+
static void fireFailedComplete() {
97+
synchronized (syncLock) {
98+
if (googleApiClient != null)
99+
googleApiClient.disconnect();
100+
googleApiClient = null;
101+
}
102+
}
103+
104+
static void onFocusChange() {
105+
synchronized (syncLock) {
106+
OneSignal.Log(OneSignal.LOG_LEVEL.DEBUG, "GMSLocationController onFocusChange!");
107+
// Google location not initialized or connected yet
108+
if (googleApiClient == null || !googleApiClient.realInstance().isConnected())
109+
return;
110+
111+
if (googleApiClient != null) {
112+
GoogleApiClient googleApiClient = GMSLocationController.googleApiClient.realInstance();
113+
if (locationUpdateListener != null)
114+
LocationServices.FusedLocationApi.removeLocationUpdates(googleApiClient, locationUpdateListener);
115+
locationUpdateListener = new LocationUpdateListener(googleApiClient);
116+
}
117+
}
118+
}
119+
120+
private static class GoogleApiClientListener implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {
121+
@Override
122+
public void onConnected(Bundle bundle) {
123+
synchronized (syncLock) {
124+
PermissionsActivity.answered = false;
125+
126+
if (googleApiClient == null || googleApiClient.realInstance() == null)
127+
return;
128+
129+
OneSignal.Log(OneSignal.LOG_LEVEL.DEBUG, "LocationController GoogleApiClientListener onConnected lastLocation: " + lastLocation);
130+
if (lastLocation == null) {
131+
lastLocation = FusedLocationApiWrapper.getLastLocation(googleApiClient.realInstance());
132+
OneSignal.Log(OneSignal.LOG_LEVEL.DEBUG, "LocationController GoogleApiClientListener lastLocation: " + lastLocation);
133+
if (lastLocation != null)
134+
fireCompleteForLocation(lastLocation);
135+
}
136+
137+
locationUpdateListener = new LocationUpdateListener(googleApiClient.realInstance());
138+
}
139+
}
140+
141+
@Override
142+
public void onConnectionSuspended(int i) {
143+
fireFailedComplete();
144+
}
145+
146+
@Override
147+
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
148+
fireFailedComplete();
149+
}
150+
}
151+
152+
static class LocationUpdateListener implements LocationListener {
153+
154+
private GoogleApiClient googleApiClient;
155+
156+
// this initializer method is already synchronized from LocationController with respect to the GoogleApiClient lock
157+
LocationUpdateListener(GoogleApiClient googleApiClient) {
158+
this.googleApiClient = googleApiClient;
159+
init();
160+
}
161+
162+
private void init() {
163+
long updateInterval = BACKGROUND_UPDATE_TIME_MS;
164+
if (OneSignal.isForeground())
165+
updateInterval = FOREGROUND_UPDATE_TIME_MS;
166+
167+
if (googleApiClient != null) {
168+
LocationRequest locationRequest = LocationRequest.create()
169+
.setFastestInterval(updateInterval)
170+
.setInterval(updateInterval)
171+
.setMaxWaitTime((long) (updateInterval * 1.5))
172+
.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
173+
174+
OneSignal.Log(OneSignal.LOG_LEVEL.DEBUG, "GMSLocationController GoogleApiClient requestLocationUpdates!");
175+
FusedLocationApiWrapper.requestLocationUpdates(googleApiClient, locationRequest, this);
176+
}
177+
}
178+
179+
@Override
180+
public void onLocationChanged(Location location) {
181+
OneSignal.Log(OneSignal.LOG_LEVEL.DEBUG, "GMSLocationController onLocationChanged: " + location);
182+
lastLocation = location;
183+
}
184+
}
185+
186+
static class FusedLocationApiWrapper {
187+
@SuppressWarnings("MissingPermission")
188+
static void requestLocationUpdates(GoogleApiClient googleApiClient, LocationRequest locationRequest, LocationListener locationListener) {
189+
try {
190+
synchronized (GMSLocationController.syncLock) {
191+
if (googleApiClient.isConnected())
192+
LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient, locationRequest, locationListener);
193+
}
194+
} catch (Throwable t) {
195+
OneSignal.Log(OneSignal.LOG_LEVEL.WARN, "FusedLocationApi.requestLocationUpdates failed!", t);
196+
}
197+
}
198+
199+
@SuppressWarnings("MissingPermission")
200+
static Location getLastLocation(GoogleApiClient googleApiClient) {
201+
synchronized (GMSLocationController.syncLock) {
202+
if (googleApiClient.isConnected())
203+
return LocationServices.FusedLocationApi.getLastLocation(googleApiClient);
204+
}
205+
return null;
206+
}
207+
}
208+
}
Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
/**
2+
* Modified MIT License
3+
* <p>
4+
* Copyright 2020 OneSignal
5+
* <p>
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
* <p>
13+
* 1. The above copyright notice and this permission notice shall be included in
14+
* all copies or substantial portions of the Software.
15+
* <p>
16+
* 2. All copies of substantial portions of the Software may only be used in connection
17+
* with services provided by OneSignal.
18+
* <p>
19+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25+
* THE SOFTWARE.
26+
*/
27+
28+
package com.onesignal;
29+
30+
import android.location.Location;
31+
32+
import com.huawei.hms.location.FusedLocationProviderClient;
33+
import com.huawei.hms.location.LocationCallback;
34+
import com.huawei.hms.location.LocationRequest;
35+
import com.huawei.hms.location.LocationResult;
36+
37+
class HMSLocationController extends LocationController {
38+
39+
private static FusedLocationProviderClient hmsFusedLocationClient;
40+
static LocationUpdateListener locationUpdateListener;
41+
42+
// Started from this class or PermissionActivity
43+
static void startGetLocation() {
44+
initHuaweiLocation();
45+
}
46+
47+
private static void initHuaweiLocation() {
48+
synchronized (syncLock) {
49+
if (hmsFusedLocationClient == null) {
50+
try {
51+
hmsFusedLocationClient = com.huawei.hms.location.LocationServices.getFusedLocationProviderClient(classContext);
52+
} catch (Exception e) {
53+
OneSignal.Log(OneSignal.LOG_LEVEL.ERROR, "Huawei LocationServices getFusedLocationProviderClient failed! " + e);
54+
fireFailedComplete();
55+
return;
56+
}
57+
}
58+
if (lastLocation != null)
59+
fireCompleteForLocation(lastLocation);
60+
else
61+
hmsFusedLocationClient.getLastLocation()
62+
.addOnSuccessListener(new com.huawei.hmf.tasks.OnSuccessListener<Location>() {
63+
@Override
64+
public void onSuccess(Location location) {
65+
OneSignal.Log(OneSignal.LOG_LEVEL.WARN, "Huawei LocationServices getLastLocation returned location: " + location);
66+
if (location == null) {
67+
fireFailedComplete();
68+
return;
69+
}
70+
lastLocation = location;
71+
fireCompleteForLocation(lastLocation);
72+
locationUpdateListener = new LocationUpdateListener(hmsFusedLocationClient);
73+
}
74+
})
75+
.addOnFailureListener(new com.huawei.hmf.tasks.OnFailureListener() {
76+
@Override
77+
public void onFailure(Exception e) {
78+
OneSignal.Log(OneSignal.LOG_LEVEL.ERROR, "Huawei LocationServices getLastLocation failed!", e);
79+
fireFailedComplete();
80+
}
81+
});
82+
}
83+
}
84+
85+
static void fireFailedComplete() {
86+
synchronized (syncLock) {
87+
hmsFusedLocationClient = null;
88+
}
89+
}
90+
91+
static void onFocusChange() {
92+
synchronized (syncLock) {
93+
OneSignal.Log(OneSignal.LOG_LEVEL.DEBUG, "HMSLocationController onFocusChange!");
94+
95+
// Huawei location not initialized yet
96+
if (isHMSAvailable() && hmsFusedLocationClient == null)
97+
return;
98+
99+
if (hmsFusedLocationClient != null) {
100+
if (locationUpdateListener != null)
101+
hmsFusedLocationClient.removeLocationUpdates(locationUpdateListener);
102+
locationUpdateListener = new LocationUpdateListener(hmsFusedLocationClient);
103+
}
104+
}
105+
}
106+
107+
static class LocationUpdateListener extends LocationCallback {
108+
109+
private FusedLocationProviderClient huaweiFusedLocationProviderClient;
110+
111+
LocationUpdateListener(FusedLocationProviderClient huaweiFusedLocationProviderClient) {
112+
this.huaweiFusedLocationProviderClient = huaweiFusedLocationProviderClient;
113+
init();
114+
}
115+
116+
private void init() {
117+
long updateInterval = BACKGROUND_UPDATE_TIME_MS;
118+
if (OneSignal.isForeground())
119+
updateInterval = FOREGROUND_UPDATE_TIME_MS;
120+
121+
LocationRequest locationRequest = LocationRequest.create()
122+
.setFastestInterval(updateInterval)
123+
.setInterval(updateInterval)
124+
.setMaxWaitTime((long) (updateInterval * 1.5))
125+
.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
126+
127+
OneSignal.Log(OneSignal.LOG_LEVEL.DEBUG, "HMSLocationController Huawei LocationServices requestLocationUpdates!");
128+
huaweiFusedLocationProviderClient.requestLocationUpdates(locationRequest, this, locationHandlerThread.getLooper());
129+
}
130+
131+
@Override
132+
public void onLocationResult(LocationResult locationResult) {
133+
OneSignal.Log(OneSignal.LOG_LEVEL.DEBUG, "HMSLocationController onLocationResult: " + locationResult);
134+
if (locationResult != null)
135+
lastLocation = locationResult.getLastLocation();
136+
}
137+
}
138+
139+
}

OneSignalSDK/onesignal/src/main/java/com/onesignal/HmsMessageServiceOneSignal.java

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
package com.onesignal;
22

3-
import android.util.Log;
4-
53
import com.huawei.hms.push.HmsMessageService;
6-
import com.huawei.hms.push.RemoteMessage;
74

85
public class HmsMessageServiceOneSignal extends HmsMessageService {
96

0 commit comments

Comments
 (0)