导航菜单

页面标题

页面副标题

fieldd v4.2.4 - LocationServiceImpl.java 源代码

正在查看: fieldd v4.2.4 应用的 LocationServiceImpl.java JAVA 源代码文件

本页面展示 JAVA 反编译生成的源代码文件,支持语法高亮显示。 仅供安全研究与技术分析使用,严禁用于任何非法用途。请遵守相关法律法规。


package com.marianhello.bgloc.service;

import android.accounts.Account;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Binder;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import com.marianhello.bgloc.Config;
import com.marianhello.bgloc.ConnectivityListener;
import com.marianhello.bgloc.PluginException;
import com.marianhello.bgloc.PostLocationTask;
import com.marianhello.bgloc.ResourceResolver;
import com.marianhello.bgloc.data.BackgroundActivity;
import com.marianhello.bgloc.data.BackgroundLocation;
import com.marianhello.bgloc.data.DAOFactory;
import com.marianhello.bgloc.data.LocationDAO;
import com.marianhello.bgloc.data.LocationTransform;
import com.marianhello.bgloc.headless.AbstractTaskRunner;
import com.marianhello.bgloc.headless.ActivityTask;
import com.marianhello.bgloc.headless.LocationTask;
import com.marianhello.bgloc.headless.StationaryTask;
import com.marianhello.bgloc.headless.Task;
import com.marianhello.bgloc.headless.TaskRunner;
import com.marianhello.bgloc.headless.TaskRunnerFactory;
import com.marianhello.bgloc.provider.LocationProvider;
import com.marianhello.bgloc.provider.LocationProviderFactory;
import com.marianhello.bgloc.provider.ProviderDelegate;
import com.marianhello.bgloc.service.LocationServiceIntentBuilder;
import com.marianhello.bgloc.sync.AccountHelper;
import com.marianhello.bgloc.sync.NotificationHelper;
import com.marianhello.bgloc.sync.SyncService;
import com.marianhello.logging.LoggerManager;
import com.marianhello.logging.UncaughtExceptionLogger;
import org.chromium.content.browser.ThreadUtils;
import org.json.JSONException;
import org.slf4j.Logger;

public class LocationServiceImpl extends Service implements ProviderDelegate, LocationService {
    public static final String ACTION_BROADCAST = ".broadcast";
    public static final int MSG_ON_ABORT_REQUESTED = 106;
    public static final int MSG_ON_ACTIVITY = 103;
    public static final int MSG_ON_ERROR = 100;
    public static final int MSG_ON_HTTP_AUTHORIZATION = 107;
    public static final int MSG_ON_LOCATION = 101;
    public static final int MSG_ON_SERVICE_STARTED = 104;
    public static final int MSG_ON_SERVICE_STOPPED = 105;
    public static final int MSG_ON_STATIONARY = 102;
    private static int NOTIFICATION_ID = 1;
    private static boolean sIsRunning = false;
    private static LocationProviderFactory sLocationProviderFactory;
    private static LocationTransform sLocationTransform;
    private Logger logger;
    private Config mConfig;
    private HandlerThread mHandlerThread;
    private TaskRunner mHeadlessTaskRunner;
    private String mHeadlessTaskRunnerClass;
    private LocationDAO mLocationDAO;
    private PostLocationTask mPostLocationTask;
    private LocationProvider mProvider;
    private ResourceResolver mResolver;
    private ServiceHandler mServiceHandler;
    private Account mSyncAccount;
    private final IBinder mBinder = new LocalBinder();
    private long mServiceId = -1;
    private boolean mIsInForeground = false;
    private BroadcastReceiver connectivityChangeReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            boolean isNetworkAvailable = LocationServiceImpl.this.isNetworkAvailable();
            LocationServiceImpl.this.mPostLocationTask.setHasConnectivity(isNetworkAvailable);
            LocationServiceImpl.this.logger.info("Network condition changed has connectivity: {}", Boolean.valueOf(isNetworkAvailable));
        }
    };

    private void processMessage(String str) {
    }

    private class ServiceHandler extends Handler {
        public ServiceHandler(Looper looper) {
            super(looper);
        }

        @Override
        public void handleMessage(Message message) {
            super.handleMessage(message);
        }
    }

    @Override
    public IBinder onBind(Intent intent) {
        this.logger.debug("Client binds to service");
        return this.mBinder;
    }

    @Override
    public void onRebind(Intent intent) {
        this.logger.debug("Client rebinds to service");
        super.onRebind(intent);
    }

    @Override
    public boolean onUnbind(Intent intent) {
        this.logger.debug("All clients have been unbound from service");
        return true;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        sIsRunning = false;
        UncaughtExceptionLogger.register(this);
        Logger logger = LoggerManager.getLogger(LocationServiceImpl.class);
        this.logger = logger;
        logger.info("Creating LocationServiceImpl");
        this.mServiceId = System.currentTimeMillis();
        if (this.mHandlerThread == null) {
            this.mHandlerThread = new HandlerThread("LocationServiceImpl.Thread", 10);
        }
        this.mHandlerThread.start();
        this.mServiceHandler = new ServiceHandler(this.mHandlerThread.getLooper());
        ResourceResolver newInstance = ResourceResolver.newInstance(this);
        this.mResolver = newInstance;
        this.mSyncAccount = AccountHelper.CreateSyncAccount(this, newInstance.getAccountName(), this.mResolver.getAccountType());
        String authority = this.mResolver.getAuthority();
        ContentResolver.setIsSyncable(this.mSyncAccount, authority, 1);
        ContentResolver.setSyncAutomatically(this.mSyncAccount, authority, true);
        this.mLocationDAO = DAOFactory.createLocationDAO(this);
        this.mPostLocationTask = new PostLocationTask(this.mLocationDAO, new PostLocationTask.PostLocationTaskListener() {
            @Override
            public void onRequestedAbortUpdates() {
                LocationServiceImpl.this.handleRequestedAbortUpdates();
            }

            @Override
            public void onHttpAuthorizationUpdates() {
                LocationServiceImpl.this.handleHttpAuthorizationUpdates();
            }

            @Override
            public void onSyncRequested() {
                SyncService.sync(LocationServiceImpl.this.mSyncAccount, LocationServiceImpl.this.mResolver.getAuthority(), false);
            }
        }, new ConnectivityListener() {
            @Override
            public boolean hasConnectivity() {
                return LocationServiceImpl.this.isNetworkAvailable();
            }
        });
        registerReceiver(this.connectivityChangeReceiver, new IntentFilter("android.net.conn.CONNECTIVITY_CHANGE"));
        NotificationHelper.registerServiceChannel(this);
    }

    @Override
    public void onDestroy() {
        this.logger.info("Destroying LocationServiceImpl");
        LocationProvider locationProvider = this.mProvider;
        if (locationProvider != null) {
            locationProvider.onDestroy();
        }
        if (this.mHandlerThread != null) {
            this.mHandlerThread.quitSafely();
        }
        PostLocationTask postLocationTask = this.mPostLocationTask;
        if (postLocationTask != null) {
            postLocationTask.shutdown();
        }
        unregisterReceiver(this.connectivityChangeReceiver);
        sIsRunning = false;
        super.onDestroy();
    }

    @Override
    public void onTaskRemoved(Intent intent) {
        this.logger.debug("Task has been removed");
        if (getConfig().getStopOnTerminate().booleanValue()) {
            this.logger.info("Stopping self");
            stopSelf();
        } else {
            this.logger.info("Continue running in background");
        }
        super.onTaskRemoved(intent);
    }

    @Override
    public int onStartCommand(Intent intent, int i, int i2) {
        if (intent == null) {
            start();
            return 1;
        }
        boolean containsCommand = LocationServiceIntentBuilder.containsCommand(intent);
        Logger logger = this.logger;
        Object[] objArr = new Object[3];
        objArr[0] = sIsRunning ? "STARTED" : "NOT STARTED";
        objArr[1] = containsCommand ? Integer.valueOf(LocationServiceIntentBuilder.getCommand(intent).getId()) : "N/A";
        objArr[2] = Integer.valueOf(i2);
        logger.debug(String.format("Service in [%s] state. cmdId: [%s]. startId: [%d]", objArr));
        if (containsCommand) {
            LocationServiceIntentBuilder.Command command = LocationServiceIntentBuilder.getCommand(intent);
            processCommand(command.getId(), command.getArgument());
        } else {
            startForegroundService();
        }
        if (LocationServiceIntentBuilder.containsMessage(intent)) {
            processMessage(LocationServiceIntentBuilder.getMessage(intent));
        }
        return 1;
    }

    private void processCommand(int i, Object obj) {
        try {
            switch (i) {
                case 0:
                    start();
                    break;
                case 1:
                    startForegroundService();
                    break;
                case 2:
                    stop();
                    break;
                case 3:
                    stopForeground();
                    break;
                case 4:
                    startForeground();
                    break;
                case 5:
                    configure((Config) obj);
                    break;
                case 6:
                    registerHeadlessTask((String) obj);
                    break;
                case 7:
                    startHeadlessTask();
                    break;
                case 8:
                    stopHeadlessTask();
                    break;
                default:
                    return;
            }
        } catch (Exception e) {
            this.logger.error("processCommand: exception", (Throwable) e);
        }
    }

    @Override
    public synchronized void start() {
        if (sIsRunning) {
            return;
        }
        if (this.mConfig == null) {
            this.logger.warn("Attempt to start unconfigured service. Will use stored or default.");
            this.mConfig = getConfig();
        }
        this.logger.debug("Will start service with: {}", this.mConfig.toString());
        this.mPostLocationTask.setConfig(this.mConfig);
        this.mPostLocationTask.clearQueue();
        LocationProviderFactory locationProviderFactory = sLocationProviderFactory;
        if (locationProviderFactory == null) {
            locationProviderFactory = new LocationProviderFactory(this);
        }
        LocationProvider locationProviderFactory2 = locationProviderFactory.getInstance(this.mConfig.getLocationProvider());
        this.mProvider = locationProviderFactory2;
        locationProviderFactory2.setDelegate(this);
        this.mProvider.onCreate();
        this.mProvider.onConfigure(this.mConfig);
        sIsRunning = true;
        ThreadUtils.runOnUiThreadBlocking(new Runnable() {
            @Override
            public void run() {
                LocationServiceImpl.this.mProvider.onStart();
                if (LocationServiceImpl.this.mConfig.getStartForeground().booleanValue()) {
                    LocationServiceImpl.this.startForeground();
                }
            }
        });
        Bundle bundle = new Bundle();
        bundle.putInt("action", MSG_ON_SERVICE_STARTED);
        bundle.putLong("serviceId", this.mServiceId);
        broadcastMessage(bundle);
    }

    @Override
    public synchronized void startForegroundService() {
        start();
        startForeground();
    }

    @Override
    public synchronized void stop() {
        if (sIsRunning) {
            LocationProvider locationProvider = this.mProvider;
            if (locationProvider != null) {
                locationProvider.onStop();
            }
            stopForeground(true);
            stopSelf();
            broadcastMessage(MSG_ON_SERVICE_STOPPED);
            sIsRunning = false;
        }
    }

    @Override
    public void startForeground() {
        if (!sIsRunning || this.mIsInForeground) {
            return;
        }
        Config config = getConfig();
        Notification notification = new NotificationHelper.NotificationFactory(this).getNotification(config.getNotificationTitle(), config.getNotificationText(), config.getLargeNotificationIcon(), config.getSmallNotificationIcon(), config.getNotificationIconColor());
        LocationProvider locationProvider = this.mProvider;
        if (locationProvider != null) {
            locationProvider.onCommand(1, 1);
        }
        super.startForeground(NOTIFICATION_ID, notification);
        this.mIsInForeground = true;
    }

    @Override
    public synchronized void stopForeground() {
        if (sIsRunning && this.mIsInForeground) {
            stopForeground(true);
            LocationProvider locationProvider = this.mProvider;
            if (locationProvider != null) {
                locationProvider.onCommand(1, 0);
            }
            this.mIsInForeground = false;
        }
    }

    @Override
    public synchronized void configure(Config config) {
        final Config config2 = this.mConfig;
        if (config2 == null) {
            this.mConfig = config;
            return;
        }
        this.mConfig = config;
        this.mPostLocationTask.setConfig(config);
        ThreadUtils.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                if (LocationServiceImpl.sIsRunning) {
                    if (config2.getStartForeground().booleanValue() && !LocationServiceImpl.this.mConfig.getStartForeground().booleanValue()) {
                        LocationServiceImpl.this.stopForeground(true);
                    }
                    if (LocationServiceImpl.this.mConfig.getStartForeground().booleanValue()) {
                        if (!config2.getStartForeground().booleanValue()) {
                            LocationServiceImpl.this.startForeground();
                        } else {
                            ((NotificationManager) LocationServiceImpl.this.getSystemService("notification")).notify(LocationServiceImpl.NOTIFICATION_ID, new NotificationHelper.NotificationFactory(LocationServiceImpl.this).getNotification(LocationServiceImpl.this.mConfig.getNotificationTitle(), LocationServiceImpl.this.mConfig.getNotificationText(), LocationServiceImpl.this.mConfig.getLargeNotificationIcon(), LocationServiceImpl.this.mConfig.getSmallNotificationIcon(), LocationServiceImpl.this.mConfig.getNotificationIconColor()));
                        }
                    }
                }
                if (config2.getLocationProvider() != LocationServiceImpl.this.mConfig.getLocationProvider()) {
                    boolean isStarted = LocationServiceImpl.this.mProvider.isStarted();
                    LocationServiceImpl.this.mProvider.onDestroy();
                    LocationProviderFactory locationProviderFactory = new LocationProviderFactory(LocationServiceImpl.this);
                    LocationServiceImpl locationServiceImpl = LocationServiceImpl.this;
                    locationServiceImpl.mProvider = locationProviderFactory.getInstance(locationServiceImpl.mConfig.getLocationProvider());
                    LocationServiceImpl.this.mProvider.setDelegate(LocationServiceImpl.this);
                    LocationServiceImpl.this.mProvider.onCreate();
                    LocationServiceImpl.this.mProvider.onConfigure(LocationServiceImpl.this.mConfig);
                    if (isStarted) {
                        LocationServiceImpl.this.mProvider.onStart();
                        return;
                    }
                    return;
                }
                LocationServiceImpl.this.mProvider.onConfigure(LocationServiceImpl.this.mConfig);
            }
        });
    }

    @Override
    public synchronized void registerHeadlessTask(String str) {
        this.logger.debug("Registering headless task");
        this.mHeadlessTaskRunnerClass = str;
    }

    @Override
    public synchronized void startHeadlessTask() {
        if (this.mHeadlessTaskRunnerClass != null) {
            try {
                TaskRunner taskRunner = new TaskRunnerFactory().getTaskRunner(this.mHeadlessTaskRunnerClass);
                this.mHeadlessTaskRunner = taskRunner;
                ((AbstractTaskRunner) taskRunner).setContext(this);
            } catch (Exception e) {
                this.logger.error("Headless task start failed: {}", e.getMessage());
            }
        }
    }

    @Override
    public synchronized void stopHeadlessTask() {
        this.mHeadlessTaskRunner = null;
    }

    @Override
    public synchronized void executeProviderCommand(final int i, final int i2) {
        if (this.mProvider == null) {
            return;
        }
        ThreadUtils.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                LocationServiceImpl.this.mProvider.onCommand(i, i2);
            }
        });
    }

    @Override
    public void onLocation(BackgroundLocation backgroundLocation) {
        this.logger.debug("New location {}", backgroundLocation.toString());
        BackgroundLocation transformLocation = transformLocation(backgroundLocation);
        if (transformLocation == null) {
            this.logger.debug("Skipping location as requested by the locationTransform");
            return;
        }
        Bundle bundle = new Bundle();
        bundle.putInt("action", MSG_ON_LOCATION);
        bundle.putParcelable("payload", transformLocation);
        broadcastMessage(bundle);
        runHeadlessTask(new LocationTask(transformLocation) {
            @Override
            public void onError(String str) {
                LocationServiceImpl.this.logger.error("Location task error: {}", str);
            }

            @Override
            public void onResult(String str) {
                LocationServiceImpl.this.logger.debug("Location task result: {}", str);
            }
        });
        postLocation(transformLocation);
    }

    @Override
    public void onStationary(BackgroundLocation backgroundLocation) {
        this.logger.debug("New stationary {}", backgroundLocation.toString());
        BackgroundLocation transformLocation = transformLocation(backgroundLocation);
        if (transformLocation == null) {
            this.logger.debug("Skipping location as requested by the locationTransform");
            return;
        }
        Bundle bundle = new Bundle();
        bundle.putInt("action", MSG_ON_STATIONARY);
        bundle.putParcelable("payload", transformLocation);
        broadcastMessage(bundle);
        runHeadlessTask(new StationaryTask(transformLocation) {
            @Override
            public void onError(String str) {
                LocationServiceImpl.this.logger.error("Stationary task error: {}", str);
            }

            @Override
            public void onResult(String str) {
                LocationServiceImpl.this.logger.debug("Stationary task result: {}", str);
            }
        });
        postLocation(transformLocation);
    }

    @Override
    public void onActivity(BackgroundActivity backgroundActivity) {
        this.logger.debug("New activity {}", backgroundActivity.toString());
        Bundle bundle = new Bundle();
        bundle.putInt("action", MSG_ON_ACTIVITY);
        bundle.putParcelable("payload", backgroundActivity);
        broadcastMessage(bundle);
        runHeadlessTask(new ActivityTask(backgroundActivity) {
            @Override
            public void onError(String str) {
                LocationServiceImpl.this.logger.error("Activity task error: {}", str);
            }

            @Override
            public void onResult(String str) {
                LocationServiceImpl.this.logger.debug("Activity task result: {}", str);
            }
        });
    }

    @Override
    public void onError(PluginException pluginException) {
        Bundle bundle = new Bundle();
        bundle.putInt("action", 100);
        bundle.putBundle("payload", pluginException.toBundle());
        broadcastMessage(bundle);
    }

    private void broadcastMessage(int i) {
        Bundle bundle = new Bundle();
        bundle.putInt("action", i);
        broadcastMessage(bundle);
    }

    private void broadcastMessage(Bundle bundle) {
        Intent intent = new Intent(ACTION_BROADCAST);
        intent.putExtras(bundle);
        LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(intent);
    }

    @Override
    public Intent registerReceiver(BroadcastReceiver broadcastReceiver, IntentFilter intentFilter) {
        return super.registerReceiver(broadcastReceiver, intentFilter, null, this.mServiceHandler, 4);
    }

    @Override
    public void unregisterReceiver(BroadcastReceiver broadcastReceiver) {
        try {
            super.unregisterReceiver(broadcastReceiver);
        } catch (IllegalArgumentException unused) {
        }
    }

    public Config getConfig() {
        Config config = this.mConfig;
        if (config == null) {
            try {
                config = DAOFactory.createConfigurationDAO(this).retrieveConfiguration();
            } catch (JSONException e) {
                this.logger.error("Config exception: {}", e.getMessage());
            }
        }
        if (config == null) {
            config = Config.getDefault();
        }
        this.mConfig = config;
        return config;
    }

    public static void setLocationProviderFactory(LocationProviderFactory locationProviderFactory) {
        sLocationProviderFactory = locationProviderFactory;
    }

    private void runHeadlessTask(Task task) {
        if (this.mHeadlessTaskRunner == null) {
            return;
        }
        this.logger.debug("Running headless task: {}", task);
        this.mHeadlessTaskRunner.runTask(task);
    }

    public class LocalBinder extends Binder {
        public LocalBinder() {
        }

        public LocationServiceImpl getService() {
            return LocationServiceImpl.this;
        }
    }

    private BackgroundLocation transformLocation(BackgroundLocation backgroundLocation) {
        LocationTransform locationTransform = sLocationTransform;
        return locationTransform != null ? locationTransform.transformLocationBeforeCommit(this, backgroundLocation) : backgroundLocation;
    }

    private void postLocation(BackgroundLocation backgroundLocation) {
        this.mPostLocationTask.add(backgroundLocation);
    }

    public void handleRequestedAbortUpdates() {
        broadcastMessage(MSG_ON_ABORT_REQUESTED);
    }

    public void handleHttpAuthorizationUpdates() {
        broadcastMessage(MSG_ON_HTTP_AUTHORIZATION);
    }

    public boolean isNetworkAvailable() {
        NetworkInfo activeNetworkInfo = ((ConnectivityManager) getSystemService("connectivity")).getActiveNetworkInfo();
        return activeNetworkInfo != null && activeNetworkInfo.isConnectedOrConnecting();
    }

    public long getServiceId() {
        return this.mServiceId;
    }

    public boolean isBound() {
        return new LocationServiceInfoImpl(this).isBound();
    }

    public static boolean isRunning() {
        return sIsRunning;
    }

    public static void setLocationTransform(LocationTransform locationTransform) {
        sLocationTransform = locationTransform;
    }

    public static LocationTransform getLocationTransform() {
        return sLocationTransform;
    }
}