导航菜单

页面标题

页面副标题

Meine NEW v2.0.3616 - ScanJob.java 源代码

正在查看: Meine NEW v2.0.3616 应用的 ScanJob.java JAVA 源代码文件

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


package org.altbeacon.beacon.service;

import android.annotation.TargetApi;
import android.app.job.JobParameters;
import android.app.job.JobService;
import android.bluetooth.le.ScanRecord;
import android.bluetooth.le.ScanResult;
import android.content.ComponentName;
import android.content.Context;
import android.content.pm.PackageItemInfo;
import android.content.pm.PackageManager;
import android.content.pm.ServiceInfo;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.SystemClock;
import java.util.ArrayList;
import java.util.Iterator;
import org.altbeacon.beacon.Beacon;
import org.altbeacon.beacon.BeaconManager;
import org.altbeacon.beacon.BuildConfig;
import org.altbeacon.beacon.distance.ModelSpecificDistanceCalculator;
import org.altbeacon.beacon.logging.LogManager;
import org.altbeacon.beacon.utils.ProcessUtils;

@TargetApi(21)
public class ScanJob extends JobService {
    private static final String TAG = "ScanJob";
    private static int sOverrideImmediateScanJobId = -1;
    private static int sOverridePeriodicScanJobId = -1;
    private ScanHelper mScanHelper;
    private ScanState mScanState = null;
    private Handler mStopHandler = new Handler();
    private boolean mInitialized = false;
    private boolean mStopCalled = false;

    public class AnonymousClass1 implements Runnable {
        final JobParameters val$jobParameters;

        public AnonymousClass1(JobParameters jobParameters) {
            this.val$jobParameters = jobParameters;
        }

        @Override
        public void run() {
            boolean startScanning;
            IntentScanStrategyCoordinator intentScanStrategyCoordinator = BeaconManager.getInstanceForApplication(ScanJob.this).getIntentScanStrategyCoordinator();
            if (intentScanStrategyCoordinator != null) {
                synchronized (ScanJob.this) {
                    if (ScanJob.this.mStopCalled) {
                        LogManager.d(ScanJob.TAG, "Quitting scan job before we even start.  Somebody told us to stop.", new Object[0]);
                        ScanJob.this.jobFinished(this.val$jobParameters, false);
                        return;
                    } else {
                        LogManager.d(ScanJob.TAG, "Scan job calling IntentScanStrategyCoordinator", new Object[0]);
                        intentScanStrategyCoordinator.performPeriodicProcessing(ScanJob.this);
                        LogManager.d(ScanJob.TAG, "Scan job finished.  Calling jobFinished", new Object[0]);
                        ScanJob.this.jobFinished(this.val$jobParameters, false);
                        return;
                    }
                }
            }
            if (!ScanJob.this.initialzeScanHelper()) {
                LogManager.e(ScanJob.TAG, "Cannot allocate a scanner to look for beacons.  System resources are low.", new Object[0]);
                ScanJob.this.jobFinished(this.val$jobParameters, false);
            }
            ScanJobScheduler.getInstance().ensureNotificationProcessorSetup(ScanJob.this.getApplicationContext());
            if (this.val$jobParameters.getJobId() == ScanJob.getImmediateScanJobId(ScanJob.this)) {
                LogManager.i(ScanJob.TAG, "Running immediate scan job: instance is " + ScanJob.this, new Object[0]);
            } else {
                LogManager.i(ScanJob.TAG, "Running periodic scan job: instance is " + ScanJob.this, new Object[0]);
            }
            ArrayList arrayList = new ArrayList(ScanJobScheduler.getInstance().dumpBackgroundScanResultQueue());
            LogManager.d(ScanJob.TAG, "Processing %d queued scan results", Integer.valueOf(arrayList.size()));
            Iterator it = arrayList.iterator();
            while (it.hasNext()) {
                ScanResult scanResult = (ScanResult) it.next();
                ScanRecord scanRecord = scanResult.getScanRecord();
                if (scanRecord != null && ScanJob.this.mScanHelper != null) {
                    ScanJob.this.mScanHelper.processScanResult(scanResult.getDevice(), scanResult.getRssi(), scanRecord.getBytes(), (scanResult.getTimestampNanos() / 1000000) + (System.currentTimeMillis() - SystemClock.elapsedRealtime()));
                }
            }
            LogManager.d(ScanJob.TAG, "Done processing queued scan results", new Object[0]);
            synchronized (ScanJob.this) {
                if (ScanJob.this.mStopCalled) {
                    LogManager.d(ScanJob.TAG, "Quitting scan job before we even start.  Somebody told us to stop.", new Object[0]);
                    ScanJob.this.jobFinished(this.val$jobParameters, false);
                    return;
                }
                if (ScanJob.this.mInitialized) {
                    LogManager.d(ScanJob.TAG, "Scanning already started.  Resetting for current parameters", new Object[0]);
                    startScanning = ScanJob.this.restartScanning();
                } else {
                    startScanning = ScanJob.this.startScanning();
                }
                ScanJob.this.mStopHandler.removeCallbacksAndMessages(null);
                if (!startScanning) {
                    LogManager.i(ScanJob.TAG, "Scanning not started so Scan job is complete.", new Object[0]);
                    ScanJob.this.stopScanning();
                    ScanJob.this.mScanState.save();
                    LogManager.d(ScanJob.TAG, "ScanJob Lifecycle STOP (start fail): " + ScanJob.this, new Object[0]);
                    ScanJob.this.jobFinished(this.val$jobParameters, false);
                } else if (ScanJob.this.mScanState != null) {
                    LogManager.i(ScanJob.TAG, "Scan job running for " + ScanJob.this.mScanState.getScanJobRuntimeMillis() + " millis", new Object[0]);
                    ScanJob.this.mStopHandler.postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            LogManager.i(ScanJob.TAG, "Scan job runtime expired: " + ScanJob.this, new Object[0]);
                            ScanJob.this.stopScanning();
                            ScanJob.this.mScanState.save();
                            AnonymousClass1 anonymousClass1 = AnonymousClass1.this;
                            ScanJob.this.jobFinished(anonymousClass1.val$jobParameters, false);
                            ScanJob.this.mStopHandler.post(new Runnable() {
                                @Override
                                public void run() {
                                    ScanJob.this.scheduleNextScan();
                                }
                            });
                        }
                    }, (long) ScanJob.this.mScanState.getScanJobRuntimeMillis());
                }
            }
        }
    }

    public static int getImmediateScanJobId(Context context) {
        if (sOverrideImmediateScanJobId < 0) {
            return getJobIdFromManifest(context, "immediateScanJobId");
        }
        LogManager.i(TAG, "Using ImmediateScanJobId from static override: " + sOverrideImmediateScanJobId, new Object[0]);
        return sOverrideImmediateScanJobId;
    }

    private static int getJobIdFromManifest(Context context, String str) {
        ServiceInfo serviceInfo;
        Bundle bundle;
        try {
            serviceInfo = context.getPackageManager().getServiceInfo(new ComponentName(context, (Class<?>) ScanJob.class), 128);
        } catch (PackageManager.NameNotFoundException unused) {
            serviceInfo = null;
        }
        if (serviceInfo == null || (bundle = ((PackageItemInfo) serviceInfo).metaData) == null || bundle.get(str) == null) {
            throw new RuntimeException(android.support.v4.media.a.j("Cannot get job id from manifest.  Make sure that the ", str, " is configured in the manifest for the ScanJob."));
        }
        int i = ((PackageItemInfo) serviceInfo).metaData.getInt(str);
        LogManager.i(TAG, "Using " + str + " from manifest: " + i, new Object[0]);
        return i;
    }

    public static int getPeriodicScanJobId(Context context) {
        if (sOverrideImmediateScanJobId < 0) {
            return getJobIdFromManifest(context, "periodicScanJobId");
        }
        LogManager.i(TAG, "Using PeriodicScanJobId from static override: " + sOverridePeriodicScanJobId, new Object[0]);
        return sOverridePeriodicScanJobId;
    }

    public boolean initialzeScanHelper() {
        ScanState restore = ScanState.restore(this);
        this.mScanState = restore;
        if (restore == null) {
            return false;
        }
        ScanHelper scanHelper = new ScanHelper(this);
        this.mScanState.setLastScanStartTimeMillis(System.currentTimeMillis());
        scanHelper.setMonitoringStatus(this.mScanState.getMonitoringStatus());
        scanHelper.setRangedRegionState(this.mScanState.getRangedRegionState());
        scanHelper.setBeaconParsers(this.mScanState.getBeaconParsers());
        scanHelper.setExtraDataBeaconTracker(this.mScanState.getExtraBeaconDataTracker());
        if (scanHelper.getCycledScanner() == null) {
            try {
                scanHelper.createCycledLeScanner(this.mScanState.getBackgroundMode().booleanValue(), null);
            } catch (OutOfMemoryError unused) {
                LogManager.w(TAG, "Failed to create CycledLeScanner thread.", new Object[0]);
                return false;
            }
        }
        this.mScanHelper = scanHelper;
        return true;
    }

    public boolean restartScanning() {
        ScanHelper scanHelper;
        if (this.mScanState == null || (scanHelper = this.mScanHelper) == null) {
            return false;
        }
        if (Build.VERSION.SDK_INT >= 26) {
            scanHelper.stopAndroidOBackgroundScan();
        }
        long longValue = (this.mScanState.getBackgroundMode().booleanValue() ? this.mScanState.getBackgroundScanPeriod() : this.mScanState.getForegroundScanPeriod()).longValue();
        long longValue2 = (this.mScanState.getBackgroundMode().booleanValue() ? this.mScanState.getBackgroundBetweenScanPeriod() : this.mScanState.getForegroundBetweenScanPeriod()).longValue();
        if (this.mScanHelper.getCycledScanner() != null) {
            this.mScanHelper.getCycledScanner().setScanPeriods(longValue, longValue2, this.mScanState.getBackgroundMode().booleanValue());
        }
        this.mInitialized = true;
        if (longValue <= 0) {
            LogManager.w(TAG, "Starting scan with scan period of zero.  Exiting ScanJob.", new Object[0]);
            if (this.mScanHelper.getCycledScanner() != null) {
                this.mScanHelper.getCycledScanner().stop();
            }
            return false;
        }
        if (this.mScanHelper.getRangedRegionState().size() > 0 || this.mScanHelper.getMonitoringStatus().regions().size() > 0) {
            if (this.mScanHelper.getCycledScanner() != null) {
                this.mScanHelper.getCycledScanner().start();
            }
            return true;
        }
        if (this.mScanHelper.getCycledScanner() != null) {
            this.mScanHelper.getCycledScanner().stop();
        }
        return false;
    }

    public void scheduleNextScan() {
        ScanState scanState = this.mScanState;
        if (scanState != null) {
            if (scanState.getBackgroundMode().booleanValue()) {
                startPassiveScanIfNeeded();
            } else {
                LogManager.d(TAG, "In foreground mode, schedule next scan", new Object[0]);
                ScanJobScheduler.getInstance().forceScheduleNextScan(this);
            }
        }
    }

    public static void setOverrideImmediateScanJobId(int i) {
        sOverrideImmediateScanJobId = i;
    }

    public static void setOverridePeriodicScanJobId(int i) {
        sOverridePeriodicScanJobId = i;
    }

    private void startPassiveScanIfNeeded() {
        if (this.mScanState != null) {
            String str = TAG;
            LogManager.d(str, "Checking to see if we need to start a passive scan", new Object[0]);
            if (this.mScanState.getMonitoringStatus().insideAnyRegion()) {
                LogManager.i(str, "We are inside a beacon region.  We will not scan between cycles.", new Object[0]);
                return;
            }
            if (Build.VERSION.SDK_INT < 26) {
                LogManager.d(str, "This is not Android O.  No scanning between cycles when using ScanJob", new Object[0]);
                return;
            }
            ScanHelper scanHelper = this.mScanHelper;
            if (scanHelper != null) {
                scanHelper.startAndroidOBackgroundScan(this.mScanState.getBeaconParsers());
            }
        }
    }

    public boolean startScanning() {
        BeaconManager instanceForApplication = BeaconManager.getInstanceForApplication(getApplicationContext());
        instanceForApplication.setScannerInSameProcess(true);
        if (instanceForApplication.isMainProcess()) {
            LogManager.i(TAG, "scanJob version %s is starting up on the main process", BuildConfig.VERSION_NAME);
        } else {
            String str = TAG;
            LogManager.i(str, "beaconScanJob library version %s is starting up on a separate process", BuildConfig.VERSION_NAME);
            ProcessUtils processUtils = new ProcessUtils(this);
            LogManager.i(str, "beaconScanJob PID is " + processUtils.getPid() + " with process name " + processUtils.getProcessName(), new Object[0]);
        }
        Beacon.setDistanceCalculator(new ModelSpecificDistanceCalculator(this, BeaconManager.getDistanceModelUpdateUrl()));
        return restartScanning();
    }

    public void stopScanning() {
        this.mInitialized = false;
        ScanHelper scanHelper = this.mScanHelper;
        if (scanHelper != null) {
            if (Build.VERSION.SDK_INT >= 26) {
                scanHelper.stopAndroidOBackgroundScan();
            }
            if (this.mScanHelper.getCycledScanner() != null) {
                this.mScanHelper.getCycledScanner().stop();
                this.mScanHelper.getCycledScanner().destroy();
            }
        }
        LogManager.d(TAG, "Scanning stopped", new Object[0]);
    }

    @Override
    public boolean onStartJob(JobParameters jobParameters) {
        LogManager.i(TAG, "ScanJob Lifecycle START: " + this, new Object[0]);
        new Thread(new AnonymousClass1(jobParameters)).start();
        return true;
    }

    @Override
    public boolean onStopJob(JobParameters jobParameters) {
        String str = TAG;
        LogManager.d(str, "onStopJob called", new Object[0]);
        synchronized (this) {
            this.mStopCalled = true;
            if (jobParameters.getJobId() == getPeriodicScanJobId(this)) {
                LogManager.i(str, "onStopJob called for periodic scan " + this, new Object[0]);
            } else {
                LogManager.i(str, "onStopJob called for immediate scan " + this, new Object[0]);
            }
            LogManager.i(str, "ScanJob Lifecycle STOP: " + this, new Object[0]);
            this.mStopHandler.removeCallbacksAndMessages(null);
            if (BeaconManager.getInstanceForApplication(this).getIntentScanStrategyCoordinator() != null) {
                LogManager.d(str, "ScanJob completed for intent scan strategy.", new Object[0]);
                return false;
            }
            stopScanning();
            startPassiveScanIfNeeded();
            ScanHelper scanHelper = this.mScanHelper;
            if (scanHelper != null) {
                scanHelper.terminateThreads();
            }
            return false;
        }
    }
}