这里以Gps返回位置为例:
/frameworks/base/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
// 可以看到对应的关系: 1141 method_reportLocation = env->GetMethodID(clazz, "reportLocation", "(ZLandroid/location/Location;)V");
// 位置上报,底层会回调 gnssLocationCb:
429Return<void> GnssCallback::gnssLocationCb(const GnssLocation& location) { 430 JNIEnv* env = getJniEnv(); 431 432 jobject jLocation = translateLocation(env, location); 433 bool hasLatLong = (static_cast<uint32_t>(location.gnssLocationFlags) & 434 GnssLocationFlags::HAS_LAT_LONG) != 0; 435 436 env->CallVoidMethod(mCallbacksObj, 437 method_reportLocation, ---> 对应java 侧 reportLocation 方法 438 boolToJbool(hasLatLong), 439 jLocation); 440 checkAndClearExceptionFromCallback(env, __FUNCTION__); 441 env->DeleteLocalRef(jLocation); 442 return Void(); 443}
1585 private void reportLocation(boolean hasLatLong, Location location) { 1586 sendMessage(REPORT_LOCATION, hasLatLong ? 1 : 0, location); 1587 }
消息处理,然后调用 handleReportLocation方法:
1589 private void handleReportLocation(boolean hasLatLong, Location location) { 1590 if (location.hasSpeed()) { 1591 mItarSpeedLimitExceeded = location.getSpeed() > ITAR_SPEED_LIMIT_METERS_PER_SECOND; 1592 } 1593 1594 if (mItarSpeedLimitExceeded) { 1595 Log.i(TAG, "Hal reported a speed in excess of ITAR limit." + 1596 " GPS/GNSS Navigation output blocked."); 1597 if (mStarted) { 1598 mGnssMetrics.logReceivedLocationStatus(false); 1599 } 1600 return; // No output of location allowed 1601 } 1602 1603 if (VERBOSE) Log.v(TAG, "reportLocation " + location.toString()); 1604 1605 // It would be nice to push the elapsed real-time timestamp 1606 // further down the stack, but this is still useful 1607 location.setElapsedRealtimeNanos(SystemClock.elapsedRealtimeNanos()); 1608 location.setExtras(mLocationExtras.getBundle()); 1609 1610 try { 1611 mILocationManager.reportLocation(location, false); ---> 在LMS new GnssLocationProvider传下来,看下面两张图 1612 } catch (RemoteException e) { 1613 Log.e(TAG, "RemoteException calling reportLocation"); 1614 }
那就是调用到 LMS(LocationManagerService)
2835 public void reportLocation(Location location, boolean passive) { 2836 checkCallerIsProvider(); 2837 2838 if (!location.isComplete()) { 2839 Log.w(TAG, "Dropping incomplete location: " + location); 2840 return; 2841 } 2842 2843 mLocationHandler.removeMessages(MSG_LOCATION_CHANGED, location); 2844 Message m = Message.obtain(mLocationHandler, MSG_LOCATION_CHANGED, location); ---> 发给handlemessage处理 2845 m.arg1 = (passive ? 1 : 0); 2846 mLocationHandler.sendMessageAtFrontOfQueue(m); 2847 }
3081 private void handleLocationChanged(Location location, boolean passive) { 3082 // create a working copy of the incoming Location so that the service can modify it without 3083 // disturbing the caller's copy 3084 Location myLocation = new Location(location); 3085 String provider = myLocation.getProvider(); 3086 3087 // set "isFromMockProvider" bit if location came from a mock provider. we do not clear this 3088 // bit if location did not come from a mock provider because passive/fused providers can 3089 // forward locations from mock providers, and should not grant them legitimacy in doing so. 3090 if (!myLocation.isFromMockProvider() && isMockProvider(provider)) { 3091 myLocation.setIsFromMockProvider(true); 3092 } 3093 3094 synchronized (mLock) { 3095 if (isAllowedByCurrentUserSettingsLocked(provider)) { 3096 if (!passive) { 3097 // notify passive provider of the new location 3098 mPassiveProvider.updateLocation(myLocation); 3099 } 3100 handleLocationChangedLocked(myLocation, passive); 3101 } 3102 } 3103 }
2882 private void handleLocationChangedLocked(Location location, boolean passive) { 2883 if (D) Log.d(TAG, "incoming location: " + location); 2884 long now = SystemClock.elapsedRealtime(); 2885 String provider = (passive ? LocationManager.PASSIVE_PROVIDER : location.getProvider()); 2886 // Skip if the provider is unknown. 2887 LocationProviderInterface p = mProvidersByName.get(provider); 2888 if (p == null) return; 2889 updateLastLocationLocked(location, provider); 2890 // mLastLocation should have been updated from the updateLastLocationLocked call above. 2891 Location lastLocation = mLastLocation.get(provider); 2892 if (lastLocation == null) { 2893 Log.e(TAG, "handleLocationChangedLocked() updateLastLocation failed"); 2894 return; 2895 } 2896 2897 // Update last known coarse interval location if enough time has passed. 2898 Location lastLocationCoarseInterval = mLastLocationCoarseInterval.get(provider); 2899 if (lastLocationCoarseInterval == null) { 2900 lastLocationCoarseInterval = new Location(location); 2901 mLastLocationCoarseInterval.put(provider, lastLocationCoarseInterval); 2902 } 2903 long timeDiffNanos = location.getElapsedRealtimeNanos() 2904 - lastLocationCoarseInterval.getElapsedRealtimeNanos(); 2905 if (timeDiffNanos > LocationFudger.FASTEST_INTERVAL_MS * NANOS_PER_MILLI) { 2906 lastLocationCoarseInterval.set(location); 2907 } 2908 // Don't ever return a coarse location that is more recent than the allowed update 2909 // interval (i.e. don't allow an app to keep registering and unregistering for 2910 // location updates to overcome the minimum interval). 2911 Location noGPSLocation = 2912 lastLocationCoarseInterval.getExtraLocation(Location.EXTRA_NO_GPS_LOCATION); 2913 2914 // Skip if there are no UpdateRecords for this provider. 2915 ArrayList<UpdateRecord> records = mRecordsByProvider.get(provider); 2916 if (records == null || records.size() == 0) return; 2917 2918 // Fetch coarse location 2919 Location coarseLocation = null; 2920 if (noGPSLocation != null) { 2921 coarseLocation = mLocationFudger.getOrCreate(noGPSLocation); 2922 } 2923 2924 // Fetch latest status update time 2925 long newStatusUpdateTime = p.getStatusUpdateTime(); 2926 2927 // Get latest status 2928 Bundle extras = new Bundle(); 2929 int status = p.getStatus(extras); 2930 2931 ArrayList<Receiver> deadReceivers = null; 2932 ArrayList<UpdateRecord> deadUpdateRecords = null; 2933 2934 // Broadcast location or status to all listeners 2935 for (UpdateRecord r : records) { 2936 Receiver receiver = r.mReceiver; 2937 boolean receiverDead = false; 2938 2939 int receiverUserId = UserHandle.getUserId(receiver.mIdentity.mUid); 2940 if (!isCurrentProfile(receiverUserId) 2941 && !isUidALocationProvider(receiver.mIdentity.mUid)) { 2942 if (D) { 2943 Log.d(TAG, "skipping loc update for background user " + receiverUserId + 2944 " (current user: " + mCurrentUserId + ", app: " + 2945 receiver.mIdentity.mPackageName + ")"); 2946 } 2947 continue; 2948 } 2949 2950 if (mBlacklist.isBlacklisted(receiver.mIdentity.mPackageName)) { 2951 if (D) { 2952 Log.d(TAG, "skipping loc update for blacklisted app: " + 2953 receiver.mIdentity.mPackageName); 2954 } 2955 continue; 2956 } 2957 2958 if (!reportLocationAccessNoThrow( 2959 receiver.mIdentity.mPid, 2960 receiver.mIdentity.mUid, 2961 receiver.mIdentity.mPackageName, 2962 receiver.mAllowedResolutionLevel)) { 2963 if (D) { 2964 Log.d(TAG, "skipping loc update for no op app: " + 2965 receiver.mIdentity.mPackageName); 2966 } 2967 continue; 2968 } 2969 //coarse location 和 fine location 是有区别的,加了一个偏移量的逻辑 2970 Location notifyLocation; 2971 if (receiver.mAllowedResolutionLevel < RESOLUTION_LEVEL_FINE) { 2972 notifyLocation = coarseLocation; // use coarse location 2973 } else { 2974 notifyLocation = lastLocation; // use fine location 2975 } 2976 if (notifyLocation != null) { 2977 Location lastLoc = r.mLastFixBroadcast; 2978 if ((lastLoc == null) || shouldBroadcastSafe(notifyLocation, lastLoc, r, now)) { ---> 判断是否需要回调 2979 if (lastLoc == null) { 2980 lastLoc = new Location(notifyLocation); 2981 r.mLastFixBroadcast = lastLoc; 2982 } else { 2983 lastLoc.set(notifyLocation); 2984 } 2985 if (!receiver.callLocationChangedLocked(notifyLocation)) { ---> 开始回调注册的listen 2986 Slog.w(TAG, "RemoteException calling onLocationChanged on " + receiver); 2987 receiverDead = true; 2988 } 2989 r.mRealRequest.decrementNumUpdates(); 2990 } 2991 }
977 public boolean callLocationChangedLocked(Location location) { 978 if (mListener != null) { 979 try { 980 synchronized (this) { 981 // synchronize to ensure incrementPendingBroadcastsLocked() 982 // is called before decrementPendingBroadcasts() 983 mListener.onLocationChanged(new Location(location)); ---> 回调给所注册的listener 984 // call this after broadcasting so we do not increment 985 // if we throw an exeption. 986 incrementPendingBroadcastsLocked(); 987 } 988 } catch (RemoteException e) { 989 return false; 990 } 991 } else { --->开始注册的是pending 走这里 992 Intent locationChanged = new Intent(); 993 locationChanged.putExtra(LocationManager.KEY_LOCATION_CHANGED, 994 new Location(location)); 995 try { 996 synchronized (this) { 997 // synchronize to ensure incrementPendingBroadcastsLocked() 998 // is called before decrementPendingBroadcasts() 999 mPendingIntent.send(mContext, 0, locationChanged, this, mLocationHandler, 1000 getResolutionPermission(mAllowedResolutionLevel), 1001 PendingIntentUtils.createDontSendToRestrictedAppsBundle(null)); 1002 // call this after broadcasting so we do not increment 1003 // if we throw an exeption. 1004 incrementPendingBroadcastsLocked(); 1005 } 1006 } catch (PendingIntent.CanceledException e) { 1007 return false; 1008 } 1009 } 1010 return true; 1011 }
至此,整个流程大致梳理完毕,最好抓份log,对着log梳理,如需要log可以公众号后台留言:
文章同步来自微信公众号,更多内容关注公众号:蘑菇君先生