/* * This is the source code of Telegram for Android v. 1.4.x. * It is licensed under GNU GPL v. 2 or later. * You should have received a copy of the license in this archive (see LICENSE). * * Copyright Nikolai Kudashov, 2013-2014. */ package org.telegram.android; import android.app.Activity; import android.app.AlertDialog; import android.content.Context; import android.content.DialogInterface; import android.content.pm.ActivityInfo; import android.content.res.Configuration; import android.graphics.Point; import android.graphics.Rect; import android.graphics.Typeface; import android.os.Build; import android.os.Environment; import android.view.Display; import android.view.Surface; import android.view.View; import android.view.WindowManager; import android.view.inputmethod.InputMethodManager; import android.widget.AbsListView; import android.widget.EdgeEffect; import android.widget.EditText; import android.widget.ListView; import android.widget.TextView; import org.telegram.messenger.FileLog; import org.telegram.messenger.R; import org.telegram.messenger.TLRPC; import org.telegram.ui.ApplicationLoader; import org.telegram.ui.Views.NumberPicker; import java.io.File; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.Hashtable; public class AndroidUtilities { private static final Hashtable typefaceCache = new Hashtable(); private static int prevOrientation = -10; private static boolean waitingForSms = false; private static final Object smsLock = new Object(); public static int statusBarHeight = 0; public static float density = 1; public static Point displaySize = new Point(); public static Integer photoSize = null; private static Boolean isTablet = null; static { density = ApplicationLoader.applicationContext.getResources().getDisplayMetrics().density; checkDisplaySize(); } public static void lockOrientation(Activity activity) { if (activity == null || prevOrientation != -10) { return; } try { prevOrientation = activity.getRequestedOrientation(); WindowManager manager = (WindowManager)activity.getSystemService(Activity.WINDOW_SERVICE); if (manager != null && manager.getDefaultDisplay() != null) { int rotation = manager.getDefaultDisplay().getRotation(); int orientation = activity.getResources().getConfiguration().orientation; if (rotation == Surface.ROTATION_270) { if (orientation == Configuration.ORIENTATION_PORTRAIT) { activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); } else { if (Build.VERSION.SDK_INT >= 9) { activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE); } else { activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); } } } else if (rotation == Surface.ROTATION_90) { if (orientation == Configuration.ORIENTATION_PORTRAIT) { if (Build.VERSION.SDK_INT >= 9) { activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT); } else { activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); } } else { activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); } } else if (rotation == Surface.ROTATION_0) { if (orientation == Configuration.ORIENTATION_LANDSCAPE) { activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); } else { activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); } } else { if (orientation == Configuration.ORIENTATION_LANDSCAPE) { if (Build.VERSION.SDK_INT >= 9) { activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE); } else { activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); } } else { if (Build.VERSION.SDK_INT >= 9) { activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT); } else { activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); } } } } } catch (Exception e) { FileLog.e("tmessages", e); } } public static void unlockOrientation(Activity activity) { if (activity == null) { return; } try { if (prevOrientation != -10) { activity.setRequestedOrientation(prevOrientation); prevOrientation = -10; } } catch (Exception e) { FileLog.e("tmessages", e); } } public static Typeface getTypeface(String assetPath) { synchronized (typefaceCache) { if (!typefaceCache.containsKey(assetPath)) { try { Typeface t = Typeface.createFromAsset(ApplicationLoader.applicationContext.getAssets(), assetPath); typefaceCache.put(assetPath, t); } catch (Exception e) { FileLog.e("Typefaces", "Could not get typeface '" + assetPath + "' because " + e.getMessage()); return null; } } return typefaceCache.get(assetPath); } } public static boolean isWaitingForSms() { boolean value = false; synchronized (smsLock) { value = waitingForSms; } return value; } public static void setWaitingForSms(boolean value) { synchronized (smsLock) { waitingForSms = value; } } public static void showKeyboard(View view) { if (view == null) { return; } InputMethodManager inputManager = (InputMethodManager)view.getContext().getSystemService(Context.INPUT_METHOD_SERVICE); inputManager.showSoftInput(view, InputMethodManager.SHOW_IMPLICIT); ((InputMethodManager) view.getContext().getSystemService(Context.INPUT_METHOD_SERVICE)).showSoftInput(view, 0); } public static boolean isKeyboardShowed(View view) { if (view == null) { return false; } InputMethodManager inputManager = (InputMethodManager) view.getContext().getSystemService(Context.INPUT_METHOD_SERVICE); return inputManager.isActive(view); } public static void hideKeyboard(View view) { if (view == null) { return; } InputMethodManager imm = (InputMethodManager) view.getContext().getSystemService(Context.INPUT_METHOD_SERVICE); if (!imm.isActive()) { return; } imm.hideSoftInputFromWindow(view.getWindowToken(), 0); } public static File getCacheDir() { if (Environment.getExternalStorageState() == null || Environment.getExternalStorageState().startsWith(Environment.MEDIA_MOUNTED)) { try { File file = ApplicationLoader.applicationContext.getExternalCacheDir(); if (file != null) { return file; } } catch (Exception e) { FileLog.e("tmessages", e); } } try { File file = ApplicationLoader.applicationContext.getCacheDir(); if (file != null) { return file; } } catch (Exception e) { FileLog.e("tmessages", e); } return new File(""); } public static int dp(float value) { return (int)Math.ceil(density * value); } public static float dpf2(float value) { return density * value; } public static void checkDisplaySize() { try { WindowManager manager = (WindowManager)ApplicationLoader.applicationContext.getSystemService(Context.WINDOW_SERVICE); if (manager != null) { Display display = manager.getDefaultDisplay(); if (display != null) { if(android.os.Build.VERSION.SDK_INT < 13) { displaySize.set(display.getWidth(), display.getHeight()); } else { display.getSize(displaySize); } FileLog.e("tmessages", "display size = " + displaySize.x + " " + displaySize.y); } } } catch (Exception e) { FileLog.e("tmessages", e); } } public static long makeBroadcastId(int id) { return 0x0000000100000000L | ((long)id & 0x00000000FFFFFFFFL); } public static int getMyLayerVersion(int layer) { return layer & 0xffff; } public static int getPeerLayerVersion(int layer) { return (layer >> 16) & 0xffff; } public static int setMyLayerVersion(int layer, int version) { return layer & 0xffff0000 | version; } public static int setPeerLayerVersion(int layer, int version) { return layer & 0x0000ffff | (version << 16); } public static void runOnUIThread(Runnable runnable) { runOnUIThread(runnable, 0); } public static void runOnUIThread(Runnable runnable, long delay) { if (delay == 0) { ApplicationLoader.applicationHandler.post(runnable); } else { ApplicationLoader.applicationHandler.postDelayed(runnable, delay); } } public static void cancelRunOnUIThread(Runnable runnable) { ApplicationLoader.applicationHandler.removeCallbacks(runnable); } public static boolean isTablet() { if (isTablet == null) { isTablet = ApplicationLoader.applicationContext.getResources().getBoolean(R.bool.isTablet); } return isTablet; } public static boolean isSmallTablet() { float minSide = Math.min(displaySize.x, displaySize.y) / density; return minSide <= 700; } public static int getMinTabletSide() { if (!isSmallTablet()) { int smallSide = Math.min(displaySize.x, displaySize.y); int leftSide = smallSide * 35 / 100; if (leftSide < dp(320)) { leftSide = dp(320); } return smallSide - leftSide; } else { int smallSide = Math.min(displaySize.x, displaySize.y); int maxSide = Math.max(displaySize.x, displaySize.y); int leftSide = maxSide * 35 / 100; if (leftSide < dp(320)) { leftSide = dp(320); } return Math.min(smallSide, maxSide - leftSide); } } public static int getPhotoSize() { if (photoSize == null) { if (Build.VERSION.SDK_INT >= 16) { photoSize = 1280; } else { photoSize = 800; } } return photoSize; } public static String formatTTLString(int ttl) { if (ttl < 60) { return LocaleController.formatPluralString("Seconds", ttl); } else if (ttl < 60 * 60) { return LocaleController.formatPluralString("Minutes", ttl / 60); } else if (ttl < 60 * 60 * 24) { return LocaleController.formatPluralString("Hours", ttl / 60 / 60); } else if (ttl < 60 * 60 * 24 * 7) { return LocaleController.formatPluralString("Days", ttl / 60 / 60 / 24); } else { int days = ttl / 60 / 60 / 24; if (ttl % 7 == 0) { return LocaleController.formatPluralString("Weeks", days / 7); } else { return String.format("%s %s", LocaleController.formatPluralString("Weeks", days / 7), LocaleController.formatPluralString("Days", days % 7)); } } } public static AlertDialog.Builder buildTTLAlert(final Context context, final TLRPC.EncryptedChat encryptedChat) { AlertDialog.Builder builder = new AlertDialog.Builder(context); builder.setTitle(LocaleController.getString("MessageLifetime", R.string.MessageLifetime)); final NumberPicker numberPicker = new NumberPicker(context); numberPicker.setMinValue(0); numberPicker.setMaxValue(20); if (encryptedChat.ttl > 0 && encryptedChat.ttl < 16) { numberPicker.setValue(encryptedChat.ttl); } else if (encryptedChat.ttl == 30) { numberPicker.setValue(16); } else if (encryptedChat.ttl == 60) { numberPicker.setValue(17); } else if (encryptedChat.ttl == 60 * 60) { numberPicker.setValue(18); } else if (encryptedChat.ttl == 60 * 60 * 24) { numberPicker.setValue(19); } else if (encryptedChat.ttl == 60 * 60 * 24 * 7) { numberPicker.setValue(20); } else if (encryptedChat.ttl == 0) { numberPicker.setValue(5); } numberPicker.setFormatter(new NumberPicker.Formatter() { @Override public String format(int value) { if (value == 0) { return LocaleController.getString("ShortMessageLifetimeForever", R.string.ShortMessageLifetimeForever); } else if (value >= 1 && value < 16) { return AndroidUtilities.formatTTLString(value); } else if (value == 16) { return AndroidUtilities.formatTTLString(30); } else if (value == 17) { return AndroidUtilities.formatTTLString(60); } else if (value == 18) { return AndroidUtilities.formatTTLString(60 * 60); } else if (value == 19) { return AndroidUtilities.formatTTLString(60 * 60 * 24); } else if (value == 20) { return AndroidUtilities.formatTTLString(60 * 60 * 24 * 7); } return ""; } }); builder.setView(numberPicker); builder.setNegativeButton(LocaleController.getString("Done", R.string.Done), new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { int oldValue = encryptedChat.ttl; which = numberPicker.getValue(); if (which >= 0 && which < 16) { encryptedChat.ttl = which; } else if (which == 16) { encryptedChat.ttl = 30; } else if (which == 17) { encryptedChat.ttl = 60; } else if (which == 18) { encryptedChat.ttl = 60 * 60; } else if (which == 19) { encryptedChat.ttl = 60 * 60 * 24; } else if (which == 20) { encryptedChat.ttl = 60 * 60 * 24 * 7; } if (oldValue != encryptedChat.ttl) { SendMessagesHelper.getInstance().sendTTLMessage(encryptedChat, null); MessagesStorage.getInstance().updateEncryptedChatTTL(encryptedChat); } } }); return builder; } public static void clearCursorDrawable(EditText editText) { if (editText == null || Build.VERSION.SDK_INT < 12) { return; } try { Field mCursorDrawableRes = TextView.class.getDeclaredField("mCursorDrawableRes"); mCursorDrawableRes.setAccessible(true); mCursorDrawableRes.setInt(editText, 0); } catch (Exception e) { FileLog.e("tmessages", e); } } public static int getViewInset(View view) { if (view == null || Build.VERSION.SDK_INT < 21) { return 0; } try { Field mAttachInfoField = View.class.getDeclaredField("mAttachInfo"); mAttachInfoField.setAccessible(true); Object mAttachInfo = mAttachInfoField.get(view); if (mAttachInfo != null) { Field mStableInsetsField = mAttachInfo.getClass().getDeclaredField("mStableInsets"); mStableInsetsField.setAccessible(true); Rect insets = (Rect)mStableInsetsField.get(mAttachInfo); return insets.bottom; } } catch (Exception e) { FileLog.e("tmessages", e); } return 0; } public static int getCurrentActionBarHeight() { if (isTablet()) { return dp(64); } else if (ApplicationLoader.applicationContext.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) { return dp(48); } else { return dp(56); } } public static Point getRealScreenSize() { Point size = new Point(); try { WindowManager windowManager = (WindowManager) ApplicationLoader.applicationContext.getSystemService(Context.WINDOW_SERVICE); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { windowManager.getDefaultDisplay().getRealSize(size); } else { try { Method mGetRawW = Display.class.getMethod("getRawWidth"); Method mGetRawH = Display.class.getMethod("getRawHeight"); size.set((Integer) mGetRawW.invoke(windowManager.getDefaultDisplay()), (Integer) mGetRawH.invoke(windowManager.getDefaultDisplay())); } catch (Exception e) { size.set(windowManager.getDefaultDisplay().getWidth(), windowManager.getDefaultDisplay().getHeight()); FileLog.e("tmessages", e); } } } catch (Exception e) { FileLog.e("tmessages", e); } return size; } public static void setListViewEdgeEffectColor(ListView listView, int color) { if (Build.VERSION.SDK_INT >= 21) { try { Field field = AbsListView.class.getDeclaredField("mEdgeGlowTop"); field.setAccessible(true); EdgeEffect mEdgeGlowTop = (EdgeEffect) field.get(listView); if (mEdgeGlowTop != null) { mEdgeGlowTop.setColor(color); } field = AbsListView.class.getDeclaredField("mEdgeGlowBottom"); field.setAccessible(true); EdgeEffect mEdgeGlowBottom = (EdgeEffect) field.get(listView); if (mEdgeGlowBottom != null) { mEdgeGlowBottom.setColor(color); } } catch (Exception e) { FileLog.e("tmessages", e); } } } }