diff --git a/android/src/com/mapswithme/maps/base/BaseActivityDelegate.java b/android/src/com/mapswithme/maps/base/BaseActivityDelegate.java index 2dcb963567..e14336b6dd 100644 --- a/android/src/com/mapswithme/maps/base/BaseActivityDelegate.java +++ b/android/src/com/mapswithme/maps/base/BaseActivityDelegate.java @@ -10,7 +10,6 @@ import androidx.annotation.Nullable; import com.mapswithme.util.Config; import com.mapswithme.util.CrashlyticsUtils; import com.mapswithme.util.Utils; -import com.mapswithme.util.ViewServer; import com.mapswithme.util.concurrency.UiThread; import com.mapswithme.util.log.Logger; import com.mapswithme.util.log.LoggerFactory; @@ -55,13 +54,11 @@ public class BaseActivityDelegate public void onDestroy() { logLifecycleMethod("onDestroy()"); - ViewServer.get(mActivity.get()).removeWindow(mActivity.get()); } public void onPostCreate() { logLifecycleMethod("onPostCreate()"); - ViewServer.get(mActivity.get()).addWindow(mActivity.get()); } public void onStart() @@ -77,7 +74,6 @@ public class BaseActivityDelegate public void onResume() { logLifecycleMethod("onResume()"); - ViewServer.get(mActivity.get()).setFocusedWindow(mActivity.get()); Utils.showOnLockScreen(Config.isShowOnLockScreenEnabled(), mActivity.get()); } diff --git a/android/src/com/mapswithme/util/ViewServer.java b/android/src/com/mapswithme/util/ViewServer.java deleted file mode 100644 index eeb266a588..0000000000 --- a/android/src/com/mapswithme/util/ViewServer.java +++ /dev/null @@ -1,844 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.mapswithme.util; - -import android.app.Activity; -import android.content.Context; -import android.content.pm.ApplicationInfo; -import android.os.Build; -import android.text.TextUtils; -import android.util.Log; -import android.view.View; -import android.view.ViewDebug; - -import java.io.BufferedReader; -import java.io.BufferedWriter; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.OutputStream; -import java.io.OutputStreamWriter; -import java.lang.reflect.Method; -import java.net.InetAddress; -import java.net.ServerSocket; -import java.net.Socket; -import java.util.HashMap; -import java.util.List; -import java.util.Map.Entry; -import java.util.concurrent.CopyOnWriteArrayList; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.locks.ReentrantReadWriteLock; - -/** - *
This class can be used to enable the use of HierarchyViewer inside an - * application. HierarchyViewer is an Android SDK tool that can be used - * to inspect and debug the user interface of running applications. For - * security reasons, HierarchyViewer does not work on production builds - * (for instance phones bought in store.) By using this class, you can - * make HierarchyViewer work on any device. You must be very careful - * however to only enable HierarchyViewer when debugging your - * application.
- * - *To use this view server, your application must require the INTERNET - * permission.
- * - *The recommended way to use this API is to register activities when - * they are created, and to unregister them when they get destroyed:
- * - *- * public class MyActivity extends Activity { - * public void onCreate(Bundle savedInstanceState) { - * super.onCreate(savedInstanceState); - * // Set content view, etc. - * ViewServer.get(this).addWindow(this); - * } - * - * public void onDestroy() { - * super.onDestroy(); - * ViewServer.get(this).removeWindow(this); - * } - * - * public void onResume() { - * super.onResume(); - * ViewServer.get(this).setFocusedWindow(this); - * } - * } - *- * - *
- * In a similar fashion, you can use this API with an InputMethodService: - *
- * - *- * public class MyInputMethodService extends InputMethodService { - * public void onCreate() { - * super.onCreate(); - * View decorView = getWindow().getWindow().getDecorView(); - * String name = "MyInputMethodService"; - * ViewServer.get(this).addWindow(decorView, name); - * } - * - * public void onDestroy() { - * super.onDestroy(); - * View decorView = getWindow().getWindow().getDecorView(); - * ViewServer.get(this).removeWindow(decorView); - * } - * - * public void onStartInput(EditorInfo attribute, boolean restarting) { - * super.onStartInput(attribute, restarting); - * View decorView = getWindow().getWindow().getDecorView(); - * ViewServer.get(this).setFocusedWindow(decorView); - * } - * } - *- */ -public class ViewServer implements Runnable { - /** - * The default port used to start view servers. - */ - private static final int VIEW_SERVER_DEFAULT_PORT = 4939; - private static final int VIEW_SERVER_MAX_CONNECTIONS = 10; - private static final String BUILD_TYPE_USER = "user"; - - // Debug facility - private static final String LOG_TAG = "ViewServer"; - - private static final String VALUE_PROTOCOL_VERSION = "4"; - private static final String VALUE_SERVER_VERSION = "4"; - - // Protocol commands - // Returns the protocol version - private static final String COMMAND_PROTOCOL_VERSION = "PROTOCOL"; - // Returns the server version - private static final String COMMAND_SERVER_VERSION = "SERVER"; - // Lists all of the available windows in the system - private static final String COMMAND_WINDOW_MANAGER_LIST = "LIST"; - // Keeps a connection open and notifies when the list of windows changes - private static final String COMMAND_WINDOW_MANAGER_AUTOLIST = "AUTOLIST"; - // Returns the focused window - private static final String COMMAND_WINDOW_MANAGER_GET_FOCUS = "GET_FOCUS"; - - private ServerSocket mServer; - private final int mPort; - - private Thread mThread; - private ExecutorService mThreadPool; - - private final List
android:debuggable
- * flag set in its manifest, the server returned by this method will
- * be a dummy object that does not do anything. This allows you to use
- * the same code in debug and release versions of your application.
- *
- * @param context A Context used to check whether the application is
- * debuggable, this can be the application context
- */
- public static ViewServer get(Context context) {
- ApplicationInfo info = context.getApplicationInfo();
- if (BUILD_TYPE_USER.equals(Build.TYPE) &&
- (info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
- if (sServer == null) {
- sServer = new ViewServer(ViewServer.VIEW_SERVER_DEFAULT_PORT);
- }
-
- if (!sServer.isRunning()) {
- try {
- sServer.start();
- } catch (IOException e) {
- Log.d(LOG_TAG, "Error:", e);
- }
- }
- } else {
- sServer = new NoopViewServer();
- }
-
- return sServer;
- }
-
- private ViewServer() {
- mPort = -1;
- }
-
- /**
- * Creates a new ViewServer associated with the specified window manager on the
- * specified local port. The server is not started by default.
- *
- * @param port The port for the server to listen to.
- *
- * @see #start()
- */
- private ViewServer(int port) {
- mPort = port;
- }
-
- /**
- * Starts the server.
- *
- * @return True if the server was successfully created, or false if it already exists.
- * @throws IOException If the server cannot be created.
- *
- * @see #stop()
- * @see #isRunning()
- * @see WindowManagerService#startViewServer(int)
- */
- public boolean start() throws IOException {
- if (mThread != null) {
- return false;
- }
-
- mThread = new Thread(this, "Local View Server [port=" + mPort + "]");
- mThreadPool = Executors.newFixedThreadPool(VIEW_SERVER_MAX_CONNECTIONS);
- mThread.start();
-
- return true;
- }
-
- /**
- * Stops the server.
- *
- * @return True if the server was stopped, false if an error occurred or if the
- * server wasn't started.
- *
- * @see #start()
- * @see #isRunning()
- * @see WindowManagerService#stopViewServer()
- */
- public boolean stop() {
- if (mThread != null) {
- mThread.interrupt();
- if (mThreadPool != null) {
- try {
- mThreadPool.shutdownNow();
- } catch (SecurityException e) {
- Log.w(LOG_TAG, "Could not stop all view server threads");
- }
- }
-
- mThreadPool = null;
- mThread = null;
-
- try {
- mServer.close();
- mServer = null;
- return true;
- } catch (IOException e) {
- Log.w(LOG_TAG, "Could not close the view server");
- }
- }
-
- mWindowsLock.writeLock().lock();
- try {
- mWindows.clear();
- } finally {
- mWindowsLock.writeLock().unlock();
- }
-
- mFocusLock.writeLock().lock();
- try {
- mFocusedWindow = null;
- } finally {
- mFocusLock.writeLock().unlock();
- }
-
- return false;
- }
-
- /**
- * Indicates whether the server is currently running.
- *
- * @return True if the server is running, false otherwise.
- *
- * @see #start()
- * @see #stop()
- * @see WindowManagerService#isViewServerRunning()
- */
- public boolean isRunning() {
- return mThread != null && mThread.isAlive();
- }
-
- /**
- * Invoke this method to register a new view hierarchy.
- *
- * @param activity The activity whose view hierarchy/window to register
- *
- * @see #addWindow(View, String)
- * @see #removeWindow(Activity)
- */
- public void addWindow(Activity activity) {
- String name = activity.getTitle().toString();
- if (TextUtils.isEmpty(name)) {
- name = activity.getClass().getCanonicalName() +
- "/0x" + System.identityHashCode(activity);
- } else {
- name += "(" + activity.getClass().getCanonicalName() + ")";
- }
- addWindow(activity.getWindow().getDecorView(), name);
- }
-
- /**
- * Invoke this method to unregister a view hierarchy.
- *
- * @param activity The activity whose view hierarchy/window to unregister
- *
- * @see #addWindow(Activity)
- * @see #removeWindow(View)
- */
- public void removeWindow(Activity activity) {
- removeWindow(activity.getWindow().getDecorView());
- }
-
- /**
- * Invoke this method to register a new view hierarchy.
- *
- * @param view A view that belongs to the view hierarchy/window to register
- * @name name The name of the view hierarchy/window to register
- *
- * @see #removeWindow(View)
- */
- public void addWindow(View view, String name) {
- mWindowsLock.writeLock().lock();
- try {
- mWindows.put(view.getRootView(), name);
- } finally {
- mWindowsLock.writeLock().unlock();
- }
- fireWindowsChangedEvent();
- }
-
- /**
- * Invoke this method to unregister a view hierarchy.
- *
- * @param view A view that belongs to the view hierarchy/window to unregister
- *
- * @see #addWindow(View, String)
- */
- public void removeWindow(View view) {
- mWindowsLock.writeLock().lock();
- try {
- mWindows.remove(view.getRootView());
- } finally {
- mWindowsLock.writeLock().unlock();
- }
- fireWindowsChangedEvent();
- }
-
- /**
- * Invoke this method to change the currently focused window.
- *
- * @param activity The activity whose view hierarchy/window hasfocus,
- * or null to remove focus
- */
- public void setFocusedWindow(Activity activity) {
- setFocusedWindow(activity.getWindow().getDecorView());
- }
-
- /**
- * Invoke this method to change the currently focused window.
- *
- * @param view A view that belongs to the view hierarchy/window that has focus,
- * or null to remove focus
- */
- public void setFocusedWindow(View view) {
- mFocusLock.writeLock().lock();
- try {
- mFocusedWindow = view == null ? null : view.getRootView();
- } finally {
- mFocusLock.writeLock().unlock();
- }
- fireFocusChangedEvent();
- }
-
- /**
- * Main server loop.
- */
- public void run() {
- try {
- mServer = new ServerSocket(mPort, VIEW_SERVER_MAX_CONNECTIONS, InetAddress.getLocalHost());
- } catch (Exception e) {
- Log.w(LOG_TAG, "Starting ServerSocket error: ", e);
- }
-
- while (mServer != null && Thread.currentThread() == mThread) {
- // Any uncaught exception will crash the system process
- try {
- Socket client = mServer.accept();
- if (mThreadPool != null) {
- mThreadPool.execute(new ViewServerWorker(client));
- } else {
- try {
- client.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- } catch (Exception e) {
- Log.w(LOG_TAG, "Connection error: ", e);
- }
- }
- }
-
- private static boolean writeValue(Socket client, String value) {
- boolean result;
- BufferedWriter out = null;
- try {
- OutputStream clientStream = client.getOutputStream();
- out = new BufferedWriter(new OutputStreamWriter(clientStream), 8 * 1024);
- out.write(value);
- out.write("\n");
- out.flush();
- result = true;
- } catch (Exception e) {
- result = false;
- } finally {
- if (out != null) {
- try {
- out.close();
- } catch (IOException e) {
- result = false;
- }
- }
- }
- return result;
- }
-
- private void fireWindowsChangedEvent() {
- for (WindowListener listener : mListeners) {
- listener.windowsChanged();
- }
- }
-
- private void fireFocusChangedEvent() {
- for (WindowListener listener : mListeners) {
- listener.focusChanged();
- }
- }
-
- private void addWindowListener(WindowListener listener) {
- if (!mListeners.contains(listener)) {
- mListeners.add(listener);
- }
- }
-
- private void removeWindowListener(WindowListener listener) {
- mListeners.remove(listener);
- }
-
- private interface WindowListener {
- void windowsChanged();
- void focusChanged();
- }
-
- private static class UncloseableOutputStream extends OutputStream {
- private final OutputStream mStream;
-
- UncloseableOutputStream(OutputStream stream) {
- mStream = stream;
- }
-
- public void close() throws IOException {
- // Don't close the stream
- }
-
- public boolean equals(Object o) {
- return mStream.equals(o);
- }
-
- public void flush() throws IOException {
- mStream.flush();
- }
-
- public int hashCode() {
- return mStream.hashCode();
- }
-
- public String toString() {
- return mStream.toString();
- }
-
- public void write(byte[] buffer, int offset, int count)
- throws IOException {
- mStream.write(buffer, offset, count);
- }
-
- public void write(byte[] buffer) throws IOException {
- mStream.write(buffer);
- }
-
- public void write(int oneByte) throws IOException {
- mStream.write(oneByte);
- }
- }
-
- private static class NoopViewServer extends ViewServer {
- private NoopViewServer() {
- }
-
- @Override
- public boolean start() throws IOException {
- return false;
- }
-
- @Override
- public boolean stop() {
- return false;
- }
-
- @Override
- public boolean isRunning() {
- return false;
- }
-
- @Override
- public void addWindow(Activity activity) {
- }
-
- @Override
- public void removeWindow(Activity activity) {
- }
-
- @Override
- public void addWindow(View view, String name) {
- }
-
- @Override
- public void removeWindow(View view) {
- }
-
- @Override
- public void setFocusedWindow(Activity activity) {
- }
-
- @Override
- public void setFocusedWindow(View view) {
- }
-
- @Override
- public void run() {
- }
- }
-
- private class ViewServerWorker implements Runnable, WindowListener {
- private final Socket mClient;
- private boolean mNeedWindowListUpdate;
- private boolean mNeedFocusedWindowUpdate;
-
- private final Object[] mLock = new Object[0];
-
- public ViewServerWorker(Socket client) {
- mClient = client;
- mNeedWindowListUpdate = false;
- mNeedFocusedWindowUpdate = false;
- }
-
- public void run() {
- BufferedReader in = null;
- try {
- in = new BufferedReader(new InputStreamReader(mClient.getInputStream()), 1024);
-
- final String request = in.readLine();
-
- String command;
- String parameters;
-
- int index = request.indexOf(' ');
- if (index == -1) {
- command = request;
- parameters = "";
- } else {
- command = request.substring(0, index);
- parameters = request.substring(index + 1);
- }
-
- boolean result;
- if (COMMAND_PROTOCOL_VERSION.equalsIgnoreCase(command)) {
- result = writeValue(mClient, VALUE_PROTOCOL_VERSION);
- } else if (COMMAND_SERVER_VERSION.equalsIgnoreCase(command)) {
- result = writeValue(mClient, VALUE_SERVER_VERSION);
- } else if (COMMAND_WINDOW_MANAGER_LIST.equalsIgnoreCase(command)) {
- result = listWindows(mClient);
- } else if (COMMAND_WINDOW_MANAGER_GET_FOCUS.equalsIgnoreCase(command)) {
- result = getFocusedWindow(mClient);
- } else if (COMMAND_WINDOW_MANAGER_AUTOLIST.equalsIgnoreCase(command)) {
- result = windowManagerAutolistLoop();
- } else {
- result = windowCommand(mClient, command, parameters);
- }
-
- if (!result) {
- Log.w(LOG_TAG, "An error occurred with the command: " + command);
- }
- } catch(IOException e) {
- Log.w(LOG_TAG, "Connection error: ", e);
- } finally {
- if (in != null) {
- try {
- in.close();
-
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- if (mClient != null) {
- try {
- mClient.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
- }
-
- private boolean windowCommand(Socket client, String command, String parameters) {
- boolean success = true;
- BufferedWriter out = null;
-
- try {
- // Find the hash code of the window
- int index = parameters.indexOf(' ');
- if (index == -1) {
- index = parameters.length();
- }
- final String code = parameters.substring(0, index);
- int hashCode = (int) Long.parseLong(code, 16);
-
- // Extract the command's parameter after the window description
- if (index < parameters.length()) {
- parameters = parameters.substring(index + 1);
- } else {
- parameters = "";
- }
-
- final View window = findWindow(hashCode);
- if (window == null) {
- return false;
- }
-
- // call stuff
- final Method dispatch = ViewDebug.class.getDeclaredMethod("dispatchCommand",
- View.class, String.class, String.class, OutputStream.class);
- dispatch.setAccessible(true);
- dispatch.invoke(null, window, command, parameters,
- new UncloseableOutputStream(client.getOutputStream()));
-
- if (!client.isOutputShutdown()) {
- out = new BufferedWriter(new OutputStreamWriter(client.getOutputStream()));
- out.write("DONE\n");
- out.flush();
- }
-
- } catch (Exception e) {
- Log.w(LOG_TAG, "Could not send command " + command +
- " with parameters " + parameters, e);
- success = false;
- } finally {
- if (out != null) {
- try {
- out.close();
- } catch (IOException e) {
- success = false;
- }
- }
- }
-
- return success;
- }
-
- private View findWindow(int hashCode) {
- if (hashCode == -1) {
- View window = null;
- mWindowsLock.readLock().lock();
- try {
- window = mFocusedWindow;
- } finally {
- mWindowsLock.readLock().unlock();
- }
- return window;
- }
-
-
- mWindowsLock.readLock().lock();
- try {
- for (Entry