diff --git a/app/src/main/java/com/emanuelef/remote_capture/activities/MainActivity.java b/app/src/main/java/com/emanuelef/remote_capture/activities/MainActivity.java index ea725e8f..eb680332 100644 --- a/app/src/main/java/com/emanuelef/remote_capture/activities/MainActivity.java +++ b/app/src/main/java/com/emanuelef/remote_capture/activities/MainActivity.java @@ -51,10 +51,10 @@ import android.widget.TextView; import com.emanuelef.remote_capture.AppsLoader; import com.emanuelef.remote_capture.ConnectionsRegister; import com.emanuelef.remote_capture.fragments.AppsFragment; +import com.emanuelef.remote_capture.interfaces.AppStateListener; import com.emanuelef.remote_capture.interfaces.AppsLoadListener; import com.emanuelef.remote_capture.model.AppDescriptor; import com.emanuelef.remote_capture.model.AppState; -import com.emanuelef.remote_capture.interfaces.AppStateListener; import com.emanuelef.remote_capture.views.AppsListView; import com.emanuelef.remote_capture.CaptureService; import com.emanuelef.remote_capture.fragments.ConnectionsFragment; @@ -88,7 +88,7 @@ public class MainActivity extends AppCompatActivity implements AppsLoadListener AppState mState; ViewPager2 viewPager2; TabLayout tabLayout; - List mStateListeners; + AppStateListener mListener; AppsListView.OnSelectedAppListener mTmpAppFilterListener; AppDescriptor mNoFilterApp; @@ -145,9 +145,6 @@ public class MainActivity extends AppCompatActivity implements AppsLoadListener } mOpenAppsWhenDone = false; - mInstalledApps = null; - mTmpAppFilterListener = null; - mStateListeners = new ArrayList<>(); CaocConfig.Builder.create() .errorDrawable(R.drawable.ic_app_crash) @@ -256,9 +253,13 @@ public class MainActivity extends AppCompatActivity implements AppsLoadListener openAppSelector(); } + public void setAppStateListener(AppStateListener listener) { + mListener = listener; + } + private void notifyAppState() { - for(AppStateListener listener: mStateListeners) - listener.appStateChanged(mState); + if(mListener != null) + mListener.appStateChanged(mState); } public void appStateReady() { @@ -454,14 +455,6 @@ public class MainActivity extends AppCompatActivity implements AppsLoadListener } } - public void addAppStateListener(AppStateListener listener) { - mStateListeners.add(listener); - } - - public void removeAppStateListener(AppStateListener listener) { - mStateListeners.remove(listener); - } - public AppState getState() { return(mState); } diff --git a/app/src/main/java/com/emanuelef/remote_capture/adapters/AppsStatsAdapter.java b/app/src/main/java/com/emanuelef/remote_capture/adapters/AppsStatsAdapter.java index 257cf11c..4f67e2ed 100644 --- a/app/src/main/java/com/emanuelef/remote_capture/adapters/AppsStatsAdapter.java +++ b/app/src/main/java/com/emanuelef/remote_capture/adapters/AppsStatsAdapter.java @@ -33,7 +33,6 @@ import androidx.recyclerview.widget.RecyclerView; import com.emanuelef.remote_capture.R; import com.emanuelef.remote_capture.Utils; -import com.emanuelef.remote_capture.activities.MainActivity; import com.emanuelef.remote_capture.model.AppDescriptor; import com.emanuelef.remote_capture.model.AppStats; @@ -45,7 +44,7 @@ import java.util.Objects; public class AppsStatsAdapter extends RecyclerView.Adapter { private static final String TAG = "ConnectionsAdapter"; - private final MainActivity mActivity; + private final Context mContext; private final LayoutInflater mLayoutInflater; private final Drawable mUnknownIcon; private View.OnClickListener mListener; @@ -65,7 +64,7 @@ public class AppsStatsAdapter extends RecyclerView.Adapter apps, Drawable unknownIcon) { + public void bindAppStats(Context context, AppStats stats, Map apps, Drawable unknownIcon) { Drawable appIcon; // NOTE: can be null @@ -77,7 +76,7 @@ public class AppsStatsAdapter extends RecyclerView.Adapter 1) - info_txt += " (" + Utils.formatNumber(activity, stats.num_connections) + ")"; + info_txt += " (" + Utils.formatNumber(context, stats.num_connections) + ")"; info.setText(info_txt); @@ -85,10 +84,10 @@ public class AppsStatsAdapter extends RecyclerView.Adapter(); } @@ -116,7 +115,7 @@ public class AppsStatsAdapter extends RecyclerView.Adapter { private static final String TAG = "ConnectionsAdapter"; - private final MainActivity mActivity; private final LayoutInflater mLayoutInflater; private final Drawable mUnknownIcon; private int mItemCount; private View.OnClickListener mListener; private Map mApps; + private final Context mContext; int mUidFilter; public static class ViewHolder extends RecyclerView.ViewHolder { @@ -69,7 +68,7 @@ public class ConnectionsAdapter extends RecyclerView.Adapter apps, Drawable unknownIcon) { + public void bindConn(Context context, ConnectionDescriptor conn, Map apps, Drawable unknownIcon) { AppDescriptor app = (apps != null) ? apps.get(conn.uid) : null; Drawable appIcon; @@ -79,7 +78,7 @@ public class ConnectionsAdapter extends RecyclerView.Adapter 0) remote.setText(conn.info); else - remote.setText(String.format(activity.getResources().getString(R.string.ip_and_port), + remote.setText(String.format(context.getResources().getString(R.string.ip_and_port), conn.dst_ip, conn.dst_port)); l7proto.setText(conn.l7proto); @@ -92,10 +91,10 @@ public class ConnectionsAdapter extends RecyclerView.Adapter mApps; - @Override - public void onAttach(@NonNull Context context) { - super.onAttach(context); - - mActivity = (MainActivity) context; - } - @Override public void onDestroy() { super.onDestroy(); - mActivity.removeAppStateListener(this); - unregisterListener(); - - mActivity = null; + unregisterConnsListener(); } @Override @@ -66,22 +57,19 @@ public class AppsFragment extends Fragment implements AppStateListener, Connecti @Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { mRecyclerView = view.findViewById(R.id.apps_stats_view); - LinearLayoutManager layoutMan = new LinearLayoutManager(mActivity); + LinearLayoutManager layoutMan = new LinearLayoutManager(getContext()); mRecyclerView.setLayoutManager(layoutMan); TextView emptyText = view.findViewById(R.id.no_apps); mRecyclerView.setEmptyView(emptyText); - mAdapter = new AppsStatsAdapter(mActivity); + mAdapter = new AppsStatsAdapter(getContext()); mRecyclerView.setAdapter(mAdapter); mHandler = new Handler(Looper.getMainLooper()); mRefreshApps = false; mAdapter.setClickListener(v -> { - if(!mActivity.canApplyTmpFilter()) - return; - int pos = mRecyclerView.getChildLayoutPosition(v); AppStats item = mAdapter.getItem(pos); @@ -89,21 +77,37 @@ public class AppsFragment extends Fragment implements AppStateListener, Connecti AppDescriptor app = mApps.get(item.getUid()); if(app != null) { - mActivity.setSelectedApp(app); - mActivity.setActivePage(MainActivity.POS_CONNECTIONS); + // TODO + //mActivity.setSelectedApp(app); + //mActivity.setActivePage(MainActivity.POS_CONNECTIONS); } } }); - registerListener(); - mActivity.addAppStateListener(this); + registerConnsListener(); - (new AppsLoader(mActivity)) + (new AppsLoader((AppCompatActivity) getActivity())) .setAppsLoadListener(this) .loadAllApps(); + + LocalBroadcastManager bcast_man = LocalBroadcastManager.getInstance(getContext()); + + /* Register for service status */ + bcast_man.registerReceiver(new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + String status = intent.getStringExtra(CaptureService.SERVICE_STATUS_KEY); + + if(CaptureService.SERVICE_STATUS_STARTED.equals(status)) { + // register the new connection register + unregisterConnsListener(); + registerConnsListener(); + } + } + }, new IntentFilter(CaptureService.ACTION_SERVICE_STATUS)); } - private void registerListener() { + private void registerConnsListener() { if (!listenerSet) { ConnectionsRegister reg = CaptureService.getConnsRegister(); @@ -114,7 +118,7 @@ public class AppsFragment extends Fragment implements AppStateListener, Connecti } } - private void unregisterListener() { + private void unregisterConnsListener() { if(listenerSet) { ConnectionsRegister reg = CaptureService.getConnsRegister(); if (reg != null) @@ -124,14 +128,6 @@ public class AppsFragment extends Fragment implements AppStateListener, Connecti } } - @Override - public void appStateChanged(AppState state) { - if(state == AppState.running) { - unregisterListener(); - registerListener(); - } - } - // NOTE: do not use synchronized as it could cause a deadlock with the ConnectionsRegister lock private void doRefreshApps() { mRefreshApps = false; diff --git a/app/src/main/java/com/emanuelef/remote_capture/fragments/ConnectionsFragment.java b/app/src/main/java/com/emanuelef/remote_capture/fragments/ConnectionsFragment.java index dbee83e5..1a5aa733 100644 --- a/app/src/main/java/com/emanuelef/remote_capture/fragments/ConnectionsFragment.java +++ b/app/src/main/java/com/emanuelef/remote_capture/fragments/ConnectionsFragment.java @@ -19,8 +19,10 @@ package com.emanuelef.remote_capture.fragments; +import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; +import android.content.IntentFilter; import android.os.Bundle; import android.os.Handler; import android.os.Looper; @@ -32,31 +34,28 @@ import android.widget.TextView; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; import androidx.fragment.app.Fragment; +import androidx.localbroadcastmanager.content.LocalBroadcastManager; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import com.emanuelef.remote_capture.AppsLoader; import com.emanuelef.remote_capture.interfaces.AppsLoadListener; import com.emanuelef.remote_capture.model.AppDescriptor; -import com.emanuelef.remote_capture.model.AppState; import com.emanuelef.remote_capture.CaptureService; import com.emanuelef.remote_capture.model.ConnectionDescriptor; import com.emanuelef.remote_capture.activities.ConnectionDetailsActivity; import com.emanuelef.remote_capture.adapters.ConnectionsAdapter; import com.emanuelef.remote_capture.ConnectionsRegister; -import com.emanuelef.remote_capture.views.AppsListView; import com.emanuelef.remote_capture.views.EmptyRecyclerView; import com.emanuelef.remote_capture.R; -import com.emanuelef.remote_capture.activities.MainActivity; -import com.emanuelef.remote_capture.interfaces.AppStateListener; import com.emanuelef.remote_capture.interfaces.ConnectionsListener; import java.util.Map; -public class ConnectionsFragment extends Fragment implements AppStateListener, ConnectionsListener, AppsListView.OnSelectedAppListener, AppsLoadListener { +public class ConnectionsFragment extends Fragment implements ConnectionsListener, AppsLoadListener { private static final String TAG = "ConnectionsFragment"; - private MainActivity mActivity; private Handler mHandler; private ConnectionsAdapter mAdapter; private View mFabDown; @@ -65,22 +64,11 @@ public class ConnectionsFragment extends Fragment implements AppStateListener, C private boolean listenerSet; private Map mApps; - @Override - public void onAttach(@NonNull Context context) { - super.onAttach(context); - - mActivity = (MainActivity) context; - } - @Override public void onDestroy() { super.onDestroy(); - mActivity.removeAppStateListener(this); - mActivity.setTmpAppFilterListener(null); - unregisterListener(); - - mActivity = null; + unregisterConnsListener(); } @Override @@ -89,7 +77,7 @@ public class ConnectionsFragment extends Fragment implements AppStateListener, C return inflater.inflate(R.layout.connections, container, false); } - private void registerListener() { + private void registerConnsListener() { if (!listenerSet) { ConnectionsRegister reg = CaptureService.getConnsRegister(); @@ -100,7 +88,7 @@ public class ConnectionsFragment extends Fragment implements AppStateListener, C } } - private void unregisterListener() { + private void unregisterConnsListener() { if(listenerSet) { ConnectionsRegister reg = CaptureService.getConnsRegister(); if (reg != null) @@ -115,13 +103,13 @@ public class ConnectionsFragment extends Fragment implements AppStateListener, C mHandler = new Handler(Looper.getMainLooper()); mFabDown = view.findViewById(R.id.fabDown); mRecyclerView = view.findViewById(R.id.connections_view); - LinearLayoutManager layoutMan = new LinearLayoutManager(mActivity); + LinearLayoutManager layoutMan = new LinearLayoutManager(getContext()); mRecyclerView.setLayoutManager(layoutMan); TextView emptyText = view.findViewById(R.id.no_connections); mRecyclerView.setEmptyView(emptyText); - mAdapter = new ConnectionsAdapter(mActivity); + mAdapter = new ConnectionsAdapter(getContext()); mRecyclerView.setAdapter(mAdapter); listenerSet = false; @@ -129,8 +117,6 @@ public class ConnectionsFragment extends Fragment implements AppStateListener, C layoutMan.getOrientation()); mRecyclerView.addItemDecoration(dividerItemDecoration);*/ - onSelectedApp(mActivity.getTmpFilter()); - mAdapter.setClickListener(v -> { int pos = mRecyclerView.getChildLayoutPosition(v); ConnectionDescriptor item = mAdapter.getItem(pos); @@ -165,14 +151,30 @@ public class ConnectionsFragment extends Fragment implements AppStateListener, C } }); - registerListener(); + registerConnsListener(); - mActivity.addAppStateListener(this); - mActivity.setTmpAppFilterListener(this); - - (new AppsLoader(mActivity)) + (new AppsLoader((AppCompatActivity) getActivity())) .setAppsLoadListener(this) .loadAllApps(); + + LocalBroadcastManager bcast_man = LocalBroadcastManager.getInstance(getContext()); + + /* Register for service status */ + bcast_man.registerReceiver(new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + String status = intent.getStringExtra(CaptureService.SERVICE_STATUS_KEY); + + if(CaptureService.SERVICE_STATUS_STARTED.equals(status)) { + // register the new connection register + unregisterConnsListener(); + registerConnsListener(); + + autoScroll = true; + showFabDown(false); + } + } + }, new IntentFilter(CaptureService.ACTION_SERVICE_STATUS)); } private void recheckScroll() { @@ -215,17 +217,6 @@ public class ConnectionsFragment extends Fragment implements AppStateListener, C super.onResume(); } - @Override - public void appStateChanged(AppState state) { - if(state == AppState.running) { - unregisterListener(); - registerListener(); - - autoScroll = true; - showFabDown(false); - } - } - // This performs an unoptimized adapter refresh private void refreshUidConnections() { ConnectionsRegister reg = CaptureService.getConnsRegister(); @@ -314,18 +305,19 @@ public class ConnectionsFragment extends Fragment implements AppStateListener, C }); } - @Override + // TODO + /* public void onSelectedApp(AppDescriptor app) { int uid = (app != null) ? app.getUid() : -1; if(mAdapter.getUidFilter() != uid) { // rather than calling refreshAllTheConnections, its better to let the register to the // job by properly scheduling the ConnectionsListener callbacks - unregisterListener(); + unregisterConnsListener(); mAdapter.setUidFilter(uid); - registerListener(); + registerConnsListener(); } - } + }*/ @Override public void onAppsInfoLoaded(Map apps) { diff --git a/app/src/main/java/com/emanuelef/remote_capture/fragments/StatusFragment.java b/app/src/main/java/com/emanuelef/remote_capture/fragments/StatusFragment.java index d667c7b5..f1d5450c 100644 --- a/app/src/main/java/com/emanuelef/remote_capture/fragments/StatusFragment.java +++ b/app/src/main/java/com/emanuelef/remote_capture/fragments/StatusFragment.java @@ -66,7 +66,7 @@ public class StatusFragment extends Fragment implements AppStateListener { @Override public void onDestroy() { - mActivity.removeAppStateListener(this); + mActivity.setAppStateListener(null); mActivity = null; super.onDestroy(); } @@ -125,7 +125,7 @@ public class StatusFragment extends Fragment implements AppStateListener { }, new IntentFilter(CaptureService.ACTION_TRAFFIC_STATS_UPDATE)); /* Important: call this after all the fields have been initialized */ - mActivity.addAppStateListener(this); + mActivity.setAppStateListener(this); } private void processStatsUpdateIntent(Intent intent) {