update to 10.0.4 (3802)

This commit is contained in:
xaxtix 2023-08-25 09:50:34 +04:00
parent 702839a853
commit 534f9f6c6e
22 changed files with 229 additions and 81 deletions

View file

@ -5460,4 +5460,12 @@ public class AndroidUtilities {
clone.position(position); clone.position(position);
return clone; return clone;
} }
public static void checkAndroidTheme(Context context, boolean open) {
// this hack is done to support prefers-color-scheme in webviews 🤦
if (context == null) {
return;
}
context.setTheme(Theme.isCurrentThemeDark() && open ? R.style.Theme_TMessages_Dark : R.style.Theme_TMessages);
}
} }

View file

@ -24,8 +24,8 @@ public class BuildVars {
public static boolean USE_CLOUD_STRINGS = true; public static boolean USE_CLOUD_STRINGS = true;
public static boolean CHECK_UPDATES = true; public static boolean CHECK_UPDATES = true;
public static boolean NO_SCOPED_STORAGE = Build.VERSION.SDK_INT <= 29; public static boolean NO_SCOPED_STORAGE = Build.VERSION.SDK_INT <= 29;
public static int BUILD_VERSION = 3801; public static int BUILD_VERSION = 3802;
public static String BUILD_VERSION_STRING = "10.0.3"; public static String BUILD_VERSION_STRING = "10.0.4";
public static int APP_ID = 4; public static int APP_ID = 4;
public static String APP_HASH = "014b35b6184100b085b0d0572f9b5103"; public static String APP_HASH = "014b35b6184100b085b0d0572f9b5103";

View file

@ -76,12 +76,12 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
private Runnable searchRunnable; private Runnable searchRunnable;
private Runnable searchRunnable2; private Runnable searchRunnable2;
private ArrayList<Object> searchResult = new ArrayList<>(); private ArrayList<Object> searchResult = new ArrayList<>();
private ArrayList<ContactsController.Contact> searchContacts = new ArrayList<>(); private final ArrayList<ContactsController.Contact> searchContacts = new ArrayList<>();
private ArrayList<TLRPC.TL_forumTopic> searchTopics = new ArrayList<>(); private final ArrayList<TLRPC.TL_forumTopic> searchTopics = new ArrayList<>();
private ArrayList<CharSequence> searchResultNames = new ArrayList<>(); private ArrayList<CharSequence> searchResultNames = new ArrayList<>();
private ArrayList<MessageObject> searchForumResultMessages = new ArrayList<>(); private final ArrayList<MessageObject> searchForumResultMessages = new ArrayList<>();
private ArrayList<MessageObject> searchResultMessages = new ArrayList<>(); private final ArrayList<MessageObject> searchResultMessages = new ArrayList<>();
private ArrayList<String> searchResultHashtags = new ArrayList<>(); private final ArrayList<String> searchResultHashtags = new ArrayList<>();
private String lastSearchText; private String lastSearchText;
private boolean searchWas; private boolean searchWas;
private int reqId = 0; private int reqId = 0;
@ -111,12 +111,13 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
public View showMoreHeader; public View showMoreHeader;
private Runnable cancelShowMoreAnimation; private Runnable cancelShowMoreAnimation;
private ArrayList<Long> filterDialogIds; private ArrayList<Long> filterDialogIds;
private final DialogsActivity dialogsActivity;
private int currentAccount = UserConfig.selectedAccount; private int currentAccount = UserConfig.selectedAccount;
private ArrayList<RecentSearchObject> recentSearchObjects = new ArrayList<>(); private ArrayList<RecentSearchObject> recentSearchObjects = new ArrayList<>();
private ArrayList<RecentSearchObject> filteredRecentSearchObjects = new ArrayList<>(); private final ArrayList<RecentSearchObject> filteredRecentSearchObjects = new ArrayList<>();
private ArrayList<RecentSearchObject> filtered2RecentSearchObjects = new ArrayList<>(); private final ArrayList<RecentSearchObject> filtered2RecentSearchObjects = new ArrayList<>();
private String filteredRecentQuery = null; private String filteredRecentQuery = null;
private LongSparseArray<RecentSearchObject> recentSearchObjectsById = new LongSparseArray<>(); private LongSparseArray<RecentSearchObject> recentSearchObjectsById = new LongSparseArray<>();
private ArrayList<FiltersView.DateData> localTipDates = new ArrayList<>(); private ArrayList<FiltersView.DateData> localTipDates = new ArrayList<>();
@ -220,9 +221,38 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
} }
} }
public DialogsSearchAdapter(Context context, int messagesSearch, int type, DefaultItemAnimator itemAnimator, boolean allowGlobalSearch) { private boolean filter(Object obj) {
if (dialogsType != DialogsActivity.DIALOGS_TYPE_START_ATTACH_BOT) {
return true;
}
// add more filters if needed
if (obj instanceof TLRPC.User) {
if (((TLRPC.User) obj).bot) {
return dialogsActivity.allowBots;
}
return dialogsActivity.allowUsers;
} else if (obj instanceof TLRPC.Chat) {
TLRPC.Chat chat = (TLRPC.Chat) obj;
if (ChatObject.isChannel(chat)) {
return dialogsActivity.allowChannels;
} else if (ChatObject.isMegagroup(chat)) {
return dialogsActivity.allowGroups || dialogsActivity.allowMegagroups;
} else {
return dialogsActivity.allowGroups || dialogsActivity.allowLegacyGroups;
}
}
return false;
}
public DialogsSearchAdapter(Context context, DialogsActivity dialogsActivity, int messagesSearch, int type, DefaultItemAnimator itemAnimator, boolean allowGlobalSearch) {
this.itemAnimator = itemAnimator; this.itemAnimator = itemAnimator;
searchAdapterHelper = new SearchAdapterHelper(false); this.dialogsActivity = dialogsActivity;
searchAdapterHelper = new SearchAdapterHelper(false) {
@Override
protected boolean filter(TLObject obj) {
return DialogsSearchAdapter.this.filter(obj);
}
};
searchAdapterHelper.setDelegate(new SearchAdapterHelper.SearchAdapterHelperDelegate() { searchAdapterHelper.setDelegate(new SearchAdapterHelper.SearchAdapterHelperDelegate() {
@Override @Override
public void onDataSetChanged(int searchId) { public void onDataSetChanged(int searchId) {
@ -872,6 +902,12 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
searchResultMessages.clear(); searchResultMessages.clear();
} }
searchWas = true; searchWas = true;
for (int i = 0; i < result.size(); ++i) {
if (!filter(result.get(i))) {
result.remove(i);
i--;
}
}
final int recentCount = filtered2RecentSearchObjects.size(); final int recentCount = filtered2RecentSearchObjects.size();
for (int a = 0; a < result.size(); a++) { for (int a = 0; a < result.size(); a++) {
Object obj = result.get(a); Object obj = result.get(a);
@ -1092,7 +1128,7 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
public int getRecentItemsCount() { public int getRecentItemsCount() {
ArrayList<RecentSearchObject> recent = searchWas ? filtered2RecentSearchObjects : filteredRecentSearchObjects; ArrayList<RecentSearchObject> recent = searchWas ? filtered2RecentSearchObjects : filteredRecentSearchObjects;
return (!recent.isEmpty() ? recent.size() + 1 : 0) + (!searchWas && !MediaDataController.getInstance(currentAccount).hints.isEmpty() ? 1 : 0); return (!recent.isEmpty() ? recent.size() + 1 : 0) + (hasHints() ? 1 : 0);
} }
public int getRecentResultsCount() { public int getRecentResultsCount() {
@ -1175,7 +1211,7 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
} }
} }
if (isRecentSearchDisplayed()) { if (isRecentSearchDisplayed()) {
int offset = (!searchWas && !MediaDataController.getInstance(currentAccount).hints.isEmpty() ? 1 : 0); int offset = (hasHints() ? 1 : 0);
ArrayList<RecentSearchObject> recent = searchWas ? filtered2RecentSearchObjects : filteredRecentSearchObjects; ArrayList<RecentSearchObject> recent = searchWas ? filtered2RecentSearchObjects : filteredRecentSearchObjects;
if (i > offset && i - 1 - offset < recent.size()) { if (i > offset && i - 1 - offset < recent.size()) {
TLObject object = recent.get(i - 1 - offset).object; TLObject object = recent.get(i - 1 - offset).object;
@ -1263,7 +1299,7 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
return false; return false;
} }
if (isRecentSearchDisplayed()) { if (isRecentSearchDisplayed()) {
int offset = (!searchWas && !MediaDataController.getInstance(currentAccount).hints.isEmpty() ? 1 : 0); int offset = (hasHints() ? 1 : 0);
ArrayList<RecentSearchObject> recent = searchWas ? filtered2RecentSearchObjects : filteredRecentSearchObjects; ArrayList<RecentSearchObject> recent = searchWas ? filtered2RecentSearchObjects : filteredRecentSearchObjects;
if (i > offset && i - 1 - offset < recent.size()) { if (i > offset && i - 1 - offset < recent.size()) {
return false; return false;
@ -1413,6 +1449,10 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
return new RecyclerListView.Holder(view); return new RecyclerListView.Holder(view);
} }
private boolean hasHints() {
return !searchWas && !MediaDataController.getInstance(currentAccount).hints.isEmpty() && (dialogsType != DialogsActivity.DIALOGS_TYPE_START_ATTACH_BOT || dialogsActivity.allowUsers);
}
@Override @Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
switch (holder.getItemViewType()) { switch (holder.getItemViewType()) {
@ -1564,7 +1604,7 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
} else { } else {
int rawPosition = position; int rawPosition = position;
if (isRecentSearchDisplayed() || !searchTopics.isEmpty() || !searchContacts.isEmpty()) { if (isRecentSearchDisplayed() || !searchTopics.isEmpty() || !searchContacts.isEmpty()) {
int offset = (!searchWas && !MediaDataController.getInstance(currentAccount).hints.isEmpty() ? 1 : 0); int offset = hasHints() ? 1 : 0;
if (position < offset) { if (position < offset) {
cell.setText(LocaleController.getString("ChatHints", R.string.ChatHints)); cell.setText(LocaleController.getString("ChatHints", R.string.ChatHints));
return; return;
@ -1768,7 +1808,7 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
return i == 0 ? VIEW_TYPE_GRAY_SECTION : VIEW_TYPE_HASHTAG_CELL; return i == 0 ? VIEW_TYPE_GRAY_SECTION : VIEW_TYPE_HASHTAG_CELL;
} }
if (isRecentSearchDisplayed()) { if (isRecentSearchDisplayed()) {
int offset = (!searchWas && !MediaDataController.getInstance(currentAccount).hints.isEmpty() ? 1 : 0); int offset = hasHints() ? 1 : 0;
if (i < offset) { if (i < offset) {
return VIEW_TYPE_CATEGORY_LIST; return VIEW_TYPE_CATEGORY_LIST;
} }
@ -1889,7 +1929,7 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
filteredRecentSearchObjects.clear(); filteredRecentSearchObjects.clear();
final int count = recentSearchObjects.size(); final int count = recentSearchObjects.size();
for (int i = 0; i < count; ++i) { for (int i = 0; i < count; ++i) {
if (delegate != null && delegate.getSearchForumDialogId() == recentSearchObjects.get(i).did) { if (delegate != null && delegate.getSearchForumDialogId() == recentSearchObjects.get(i).did || !filter(recentSearchObjects.get(i).object)) {
continue; continue;
} }
filteredRecentSearchObjects.add(recentSearchObjects.get(i)); filteredRecentSearchObjects.add(recentSearchObjects.get(i));
@ -1903,7 +1943,7 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
if (obj == null || obj.object == null) { if (obj == null || obj.object == null) {
continue; continue;
} }
if (delegate != null && delegate.getSearchForumDialogId() == obj.did) { if (delegate != null && delegate.getSearchForumDialogId() == obj.did || !filter(recentSearchObjects.get(i).object)) {
continue; continue;
} }
String title = null, username = null; String title = null, username = null;

View file

@ -66,15 +66,15 @@ public class SearchAdapterHelper {
private SearchAdapterHelperDelegate delegate; private SearchAdapterHelperDelegate delegate;
private ArrayList<Integer> pendingRequestIds = new ArrayList<>(); private final ArrayList<Integer> pendingRequestIds = new ArrayList<>();
private String lastFoundUsername = null; private String lastFoundUsername = null;
private ArrayList<TLObject> localServerSearch = new ArrayList<>(); private final ArrayList<TLObject> localServerSearch = new ArrayList<>();
private ArrayList<TLObject> globalSearch = new ArrayList<>(); private final ArrayList<TLObject> globalSearch = new ArrayList<>();
private LongSparseArray<TLObject> globalSearchMap = new LongSparseArray<>(); private final LongSparseArray<TLObject> globalSearchMap = new LongSparseArray<>();
private ArrayList<TLObject> groupSearch = new ArrayList<>(); private final ArrayList<TLObject> groupSearch = new ArrayList<>();
private LongSparseArray<TLObject> groupSearchMap = new LongSparseArray<>(); private final LongSparseArray<TLObject> groupSearchMap = new LongSparseArray<>();
private LongSparseArray<TLObject> phoneSearchMap = new LongSparseArray<>(); private final LongSparseArray<TLObject> phoneSearchMap = new LongSparseArray<>();
private ArrayList<Object> phonesSearch = new ArrayList<>(); private final ArrayList<Object> phonesSearch = new ArrayList<>();
private ArrayList<Object> localSearchResults; private ArrayList<Object> localSearchResults;
private ArrayList<DialogsSearchAdapter.RecentSearchObject> localRecentResults; private ArrayList<DialogsSearchAdapter.RecentSearchObject> localRecentResults;
@ -223,13 +223,13 @@ public class SearchAdapterHelper {
chat = chatsMap.get(peer.channel_id); chat = chatsMap.get(peer.channel_id);
} }
if (chat != null) { if (chat != null) {
if (!allowChats || canAddGroupsOnly && !ChatObject.canAddBotsToChat(chat) || !allowGlobalResults && ChatObject.isNotInChat(chat)) { if (!allowChats || canAddGroupsOnly && !ChatObject.canAddBotsToChat(chat) || !allowGlobalResults && ChatObject.isNotInChat(chat) || !filter(chat)) {
continue; continue;
} }
globalSearch.add(chat); globalSearch.add(chat);
globalSearchMap.put(-chat.id, chat); globalSearchMap.put(-chat.id, chat);
} else if (user != null) { } else if (user != null) {
if (canAddGroupsOnly || !allowBots && user.bot || !allowSelf && user.self || !allowGlobalResults && b == 1 && !user.contact) { if (canAddGroupsOnly || !allowBots && user.bot || !allowSelf && user.self || !allowGlobalResults && b == 1 && !user.contact || !filter(user)) {
continue; continue;
} }
globalSearch.add(user); globalSearch.add(user);
@ -250,13 +250,13 @@ public class SearchAdapterHelper {
chat = chatsMap.get(peer.channel_id); chat = chatsMap.get(peer.channel_id);
} }
if (chat != null) { if (chat != null) {
if (!allowChats || canAddGroupsOnly && !ChatObject.canAddBotsToChat(chat) || -chat.id == exceptDialogId) { if (!allowChats || canAddGroupsOnly && !ChatObject.canAddBotsToChat(chat) || -chat.id == exceptDialogId || !filter(chat)) {
continue; continue;
} }
localServerSearch.add(chat); localServerSearch.add(chat);
globalSearchMap.put(-chat.id, chat); globalSearchMap.put(-chat.id, chat);
} else if (user != null) { } else if (user != null) {
if (canAddGroupsOnly || !allowBots && user.bot || !allowSelf && user.self || user.id == exceptDialogId) { if (canAddGroupsOnly || !allowBots && user.bot || !allowSelf && user.self || user.id == exceptDialogId || !filter(user)) {
continue; continue;
} }
localServerSearch.add(user); localServerSearch.add(user);
@ -625,4 +625,8 @@ public class SearchAdapterHelper {
hashtagsLoadedFromDb = true; hashtagsLoadedFromDb = true;
delegate.onSetHashtags(arrayList, hashMap); delegate.onSetHashtags(arrayList, hashMap);
} }
protected boolean filter(TLObject obj) {
return true;
}
} }

View file

@ -11591,7 +11591,7 @@ public class ArticleViewer implements NotificationCenter.NotificationCenterDeleg
BlockVideoCell cell = (BlockVideoCell) view; BlockVideoCell cell = (BlockVideoCell) view;
if (cell.currentBlock == pageBlock) { if (cell.currentBlock == pageBlock) {
view.getLocationInWindow(coords); view.getLocationInWindow(coords);
if (cell == currentPlayer && videoPlayer != null && videoPlayer.firstFrameRendered) { if (cell == currentPlayer && videoPlayer != null && videoPlayer.firstFrameRendered && cell.textureView.getSurfaceTexture() != null) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
Surface surface = new Surface(cell.textureView.getSurfaceTexture()); Surface surface = new Surface(cell.textureView.getSurfaceTexture());
Bitmap bitmap = Bitmap.createBitmap(cell.textureView.getMeasuredWidth(), cell.textureView.getMeasuredHeight(), Bitmap.Config.ARGB_8888); Bitmap bitmap = Bitmap.createBitmap(cell.textureView.getMeasuredWidth(), cell.textureView.getMeasuredHeight(), Bitmap.Config.ARGB_8888);
@ -11651,6 +11651,7 @@ public class ArticleViewer implements NotificationCenter.NotificationCenterDeleg
videoCell.playFrom = player.getCurrentPosition(); videoCell.playFrom = player.getCurrentPosition();
videoCell.firstFrameRendered = false; videoCell.firstFrameRendered = false;
videoCell.textureView.setAlpha(0); videoCell.textureView.setAlpha(0);
if (textureView.getSurfaceTexture() != null) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
Surface surface = new Surface(textureView.getSurfaceTexture()); Surface surface = new Surface(textureView.getSurfaceTexture());
Bitmap bitmap = Bitmap.createBitmap(textureView.getMeasuredWidth(), textureView.getMeasuredHeight(), Bitmap.Config.ARGB_8888); Bitmap bitmap = Bitmap.createBitmap(textureView.getMeasuredWidth(), textureView.getMeasuredHeight(), Bitmap.Config.ARGB_8888);
@ -11661,6 +11662,7 @@ public class ArticleViewer implements NotificationCenter.NotificationCenterDeleg
videoCell.imageView.setImageBitmap(textureView.getBitmap()); videoCell.imageView.setImageBitmap(textureView.getBitmap());
} }
} }
}
checkVideoPlayer(); checkVideoPlayer();
} }

View file

@ -134,6 +134,12 @@ public class CheckBoxCell extends FrameLayout {
updateTextColor(); updateTextColor();
} }
public void allowMultiline() {
textView.setLines(3);
textView.setMaxLines(3);
textView.setSingleLine(false);
}
public void updateTextColor() { public void updateTextColor() {
textView.setTextColor(getThemedColor(currentType == TYPE_CHECK_BOX_DEFAULT || currentType == TYPE_CHECK_BOX_URL ? Theme.key_dialogTextBlack : Theme.key_windowBackgroundWhiteBlackText)); textView.setTextColor(getThemedColor(currentType == TYPE_CHECK_BOX_DEFAULT || currentType == TYPE_CHECK_BOX_URL ? Theme.key_dialogTextBlack : Theme.key_windowBackgroundWhiteBlackText));
textView.setLinkTextColor(getThemedColor(currentType == TYPE_CHECK_BOX_DEFAULT || currentType == TYPE_CHECK_BOX_URL ? Theme.key_dialogTextLink : Theme.key_windowBackgroundWhiteLinkText)); textView.setLinkTextColor(getThemedColor(currentType == TYPE_CHECK_BOX_DEFAULT || currentType == TYPE_CHECK_BOX_URL ? Theme.key_dialogTextLink : Theme.key_windowBackgroundWhiteLinkText));

View file

@ -1563,6 +1563,7 @@ public class AlertsCreator {
allowWrite.set(true); allowWrite.set(true);
cell[0] = new CheckBoxCell(context, 1, fragment.getResourceProvider()); cell[0] = new CheckBoxCell(context, 1, fragment.getResourceProvider());
cell[0].allowMultiline();
cell[0].setBackgroundDrawable(Theme.getSelectorDrawable(false)); cell[0].setBackgroundDrawable(Theme.getSelectorDrawable(false));
cell[0].setText(AndroidUtilities.replaceTags(LocaleController.formatString("OpenUrlOption2", R.string.OpenUrlOption2, UserObject.getUserName(user))), "", true, false); cell[0].setText(AndroidUtilities.replaceTags(LocaleController.formatString("OpenUrlOption2", R.string.OpenUrlOption2, UserObject.getUserName(user))), "", true, false);
cell[0].setPadding(LocaleController.isRTL ? AndroidUtilities.dp(16) : AndroidUtilities.dp(8), 0, LocaleController.isRTL ? AndroidUtilities.dp(8) : AndroidUtilities.dp(16), 0); cell[0].setPadding(LocaleController.isRTL ? AndroidUtilities.dp(16) : AndroidUtilities.dp(8), 0, LocaleController.isRTL ? AndroidUtilities.dp(8) : AndroidUtilities.dp(16), 0);

View file

@ -20,7 +20,9 @@ import android.graphics.PorterDuffColorFilter;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.net.Uri; import android.net.Uri;
import android.os.Build; import android.os.Build;
import android.os.Message;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Log;
import android.util.TypedValue; import android.util.TypedValue;
import android.view.Gravity; import android.view.Gravity;
import android.view.MotionEvent; import android.view.MotionEvent;
@ -31,6 +33,7 @@ import android.webkit.JavascriptInterface;
import android.webkit.PermissionRequest; import android.webkit.PermissionRequest;
import android.webkit.ValueCallback; import android.webkit.ValueCallback;
import android.webkit.WebChromeClient; import android.webkit.WebChromeClient;
import android.webkit.WebResourceRequest;
import android.webkit.WebSettings; import android.webkit.WebSettings;
import android.webkit.WebView; import android.webkit.WebView;
import android.webkit.WebViewClient; import android.webkit.WebViewClient;
@ -267,6 +270,18 @@ public class BotWebViewContainer extends FrameLayout implements NotificationCent
} }
return super.onTouchEvent(event); return super.onTouchEvent(event);
} }
@Override
protected void onAttachedToWindow() {
AndroidUtilities.checkAndroidTheme(getContext(), true);
super.onAttachedToWindow();
}
@Override
protected void onDetachedFromWindow() {
AndroidUtilities.checkAndroidTheme(getContext(), false);
super.onDetachedFromWindow();
}
}; };
webView.setBackgroundColor(getColor(Theme.key_windowBackgroundWhite)); webView.setBackgroundColor(getColor(Theme.key_windowBackgroundWhite));
WebSettings settings = webView.getSettings(); WebSettings settings = webView.getSettings();
@ -274,6 +289,7 @@ public class BotWebViewContainer extends FrameLayout implements NotificationCent
settings.setGeolocationEnabled(true); settings.setGeolocationEnabled(true);
settings.setDomStorageEnabled(true); settings.setDomStorageEnabled(true);
settings.setDatabaseEnabled(true); settings.setDatabaseEnabled(true);
settings.setSupportMultipleWindows(true);
// Hackfix text on some Xiaomi devices // Hackfix text on some Xiaomi devices
settings.setTextSize(WebSettings.TextSize.NORMAL); settings.setTextSize(WebSettings.TextSize.NORMAL);
@ -288,21 +304,14 @@ public class BotWebViewContainer extends FrameLayout implements NotificationCent
webView.setWebViewClient(new WebViewClient() { webView.setWebViewClient(new WebViewClient() {
@Override @Override
public boolean shouldOverrideUrlLoading(WebView view, String url) { public boolean shouldOverrideUrlLoading(WebView view, String url) {
Uri uriOrig = Uri.parse(mUrl);
Uri uriNew = Uri.parse(url); Uri uriNew = Uri.parse(url);
if (Browser.isInternalUri(uriNew, null)) {
boolean override;
if (isPageLoaded && (!Objects.equals(uriOrig.getHost(), uriNew.getHost()) || !Objects.equals(uriOrig.getPath(), uriNew.getPath()))) {
override = true;
if (WHITELISTED_SCHEMES.contains(uriNew.getScheme())) { if (WHITELISTED_SCHEMES.contains(uriNew.getScheme())) {
onOpenUri(uriNew); onOpenUri(uriNew);
} }
} else { return true;
override = false;
} }
return false;
return override;
} }
@Override @Override
@ -313,6 +322,22 @@ public class BotWebViewContainer extends FrameLayout implements NotificationCent
webView.setWebChromeClient(new WebChromeClient() { webView.setWebChromeClient(new WebChromeClient() {
private Dialog lastPermissionsDialog; private Dialog lastPermissionsDialog;
@Override
public boolean onCreateWindow(WebView view, boolean isDialog, boolean isUserGesture, Message resultMsg) {
WebView newWebView = new WebView(view.getContext());
newWebView.setWebViewClient(new WebViewClient() {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
onOpenUri(Uri.parse(url));
return true;
}
});
WebView.WebViewTransport transport = (WebView.WebViewTransport) resultMsg.obj;
transport.setWebView(newWebView);
resultMsg.sendToTarget();
return true;
}
@Override @Override
public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback, FileChooserParams fileChooserParams) { public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback, FileChooserParams fileChooserParams) {
Context ctx = getContext(); Context ctx = getContext();
@ -489,17 +514,8 @@ public class BotWebViewContainer extends FrameLayout implements NotificationCent
} else { } else {
Browser.openUrl(getContext(), uri, true, tryInstantView); Browser.openUrl(getContext(), uri, true, tryInstantView);
} }
} else if (suppressPopup) {
Browser.openUrl(getContext(), uri, true, tryInstantView);
} else { } else {
isRequestingPageOpen = true; Browser.openUrl(getContext(), uri, true, tryInstantView);
new AlertDialog.Builder(getContext(), resourcesProvider)
.setTitle(LocaleController.getString(R.string.OpenUrlTitle))
.setMessage(LocaleController.formatString(R.string.OpenUrlAlert2, uri.toString()))
.setPositiveButton(LocaleController.getString(R.string.Open), (dialog, which) -> Browser.openUrl(getContext(), uri, true, tryInstantView))
.setNegativeButton(LocaleController.getString(R.string.Cancel), null)
.setOnDismissListener(dialog -> isRequestingPageOpen = false)
.show();
} }
} }

View file

@ -307,6 +307,18 @@ public class EmbedBottomSheet extends BottomSheet {
setCustomView(containerLayout); setCustomView(containerLayout);
webView = new WebView(context) { webView = new WebView(context) {
@Override
protected void onAttachedToWindow() {
AndroidUtilities.checkAndroidTheme(context, true);
super.onAttachedToWindow();
}
@Override
protected void onDetachedFromWindow() {
AndroidUtilities.checkAndroidTheme(context, false);
super.onDetachedFromWindow();
}
@Override @Override
public boolean onTouchEvent(MotionEvent event) { public boolean onTouchEvent(MotionEvent event) {
boolean result = super.onTouchEvent(event); boolean result = super.onTouchEvent(event);

View file

@ -265,6 +265,18 @@ public class PhotoViewerWebView extends FrameLayout {
drawBlackBackground(canvas, getWidth(), getHeight()); drawBlackBackground(canvas, getWidth(), getHeight());
} }
} }
@Override
protected void onAttachedToWindow() {
AndroidUtilities.checkAndroidTheme(context, true);
super.onAttachedToWindow();
}
@Override
protected void onDetachedFromWindow() {
AndroidUtilities.checkAndroidTheme(context, false);
super.onDetachedFromWindow();
}
}; };
webView.getSettings().setJavaScriptEnabled(true); webView.getSettings().setJavaScriptEnabled(true);
webView.getSettings().setDomStorageEnabled(true); webView.getSettings().setDomStorageEnabled(true);

View file

@ -132,7 +132,7 @@ public class SearchViewPager extends ViewPagerFixed implements FilteredSearchVie
itemAnimator.setMoveInterpolator(new OvershootInterpolator(1.1f)); itemAnimator.setMoveInterpolator(new OvershootInterpolator(1.1f));
itemAnimator.setTranslationInterpolator(CubicBezierInterpolator.EASE_OUT_QUINT); itemAnimator.setTranslationInterpolator(CubicBezierInterpolator.EASE_OUT_QUINT);
dialogsSearchAdapter = new DialogsSearchAdapter(context, type, initialDialogsType, itemAnimator, fragment.getAllowGlobalSearch()) { dialogsSearchAdapter = new DialogsSearchAdapter(context, fragment, type, initialDialogsType, itemAnimator, fragment.getAllowGlobalSearch()) {
@Override @Override
public void notifyDataSetChanged() { public void notifyDataSetChanged() {
int itemCount = getCurrentItemCount(); int itemCount = getCurrentItemCount();

View file

@ -179,6 +179,9 @@ public class StickerCategoriesListView extends RecyclerListView {
} else if (view.getLeft() < minimumPadding) { } else if (view.getLeft() < minimumPadding) {
smoothScrollBy(-(minimumPadding - view.getLeft()), 0, CubicBezierInterpolator.EASE_OUT_QUINT); smoothScrollBy(-(minimumPadding - view.getLeft()), 0, CubicBezierInterpolator.EASE_OUT_QUINT);
} }
// if (view instanceof CategoryButton) {
// ((CategoryButton) view).play(true);
// }
if (onCategoryClick != null) { if (onCategoryClick != null) {
onCategoryClick.run(category); onCategoryClick.run(category);
} }
@ -307,7 +310,7 @@ public class StickerCategoriesListView extends RecyclerListView {
int position = getChildAdapterPosition(child); int position = getChildAdapterPosition(child);
float childT = AndroidUtilities.cascade(t, getChildCount() - 1 - position, getChildCount() - 1, 3f); float childT = AndroidUtilities.cascade(t, getChildCount() - 1 - position, getChildCount() - 1, 3f);
if (childT > 0 && child.getAlpha() <= 0) { if (childT > 0 && child.getAlpha() <= 0) {
((CategoryButton) child).play(); ((CategoryButton) child).play(false);
} }
child.setAlpha(childT); child.setAlpha(childT);
child.setScaleX(childT); child.setScaleX(childT);
@ -558,7 +561,7 @@ public class StickerCategoriesListView extends RecyclerListView {
button.setAlpha(categoriesShownT); button.setAlpha(categoriesShownT);
button.setScaleX(categoriesShownT); button.setScaleX(categoriesShownT);
button.setScaleY(categoriesShownT); button.setScaleY(categoriesShownT);
button.play(); button.play(false);
} }
} }
@ -568,7 +571,7 @@ public class StickerCategoriesListView extends RecyclerListView {
final CategoryButton button = (CategoryButton) holder.itemView; final CategoryButton button = (CategoryButton) holder.itemView;
final int position = holder.getAdapterPosition(); final int position = holder.getAdapterPosition();
button.setSelected(selectedCategoryIndex == position - 1, false); button.setSelected(selectedCategoryIndex == position - 1, false);
button.play(); button.play(false);
} }
} }
@ -598,7 +601,7 @@ public class StickerCategoriesListView extends RecyclerListView {
} }
protected boolean isTabIconsAnimationEnabled(boolean loaded) { protected boolean isTabIconsAnimationEnabled(boolean loaded) {
return LiteMode.isEnabled(LiteMode.FLAG_ANIMATED_EMOJI_KEYBOARD) && !loaded; return LiteMode.isEnabled(LiteMode.FLAG_ANIMATED_EMOJI_KEYBOARD);
} }
static int loadedCategoryIcons = 0; static int loadedCategoryIcons = 0;
@ -756,8 +759,8 @@ public class StickerCategoriesListView extends RecyclerListView {
} }
private long lastPlayed; private long lastPlayed;
public void play() { public void play(boolean force) {
if (System.currentTimeMillis() - lastPlayed > 250) { if (System.currentTimeMillis() - lastPlayed > 250 || force) {
lastPlayed = System.currentTimeMillis(); lastPlayed = System.currentTimeMillis();
RLottieDrawable drawable = getAnimatedDrawable(); RLottieDrawable drawable = getAnimatedDrawable();
if (drawable == null && getImageReceiver() != null) { if (drawable == null && getImageReceiver() != null) {

View file

@ -1544,7 +1544,19 @@ public class WebPlayerView extends ViewGroup implements VideoPlayer.VideoPlayerD
addView(aspectRatioFrameLayout, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, Gravity.CENTER)); addView(aspectRatioFrameLayout, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, Gravity.CENTER));
interfaceName = "JavaScriptInterface"; interfaceName = "JavaScriptInterface";
webView = new WebView(context); webView = new WebView(context) {
@Override
protected void onAttachedToWindow() {
AndroidUtilities.checkAndroidTheme(context, true);
super.onAttachedToWindow();
}
@Override
protected void onDetachedFromWindow() {
AndroidUtilities.checkAndroidTheme(context, false);
super.onDetachedFromWindow();
}
};
webView.addJavascriptInterface(new JavaScriptInterface(value -> { webView.addJavascriptInterface(new JavaScriptInterface(value -> {
if (currentTask != null && !currentTask.isCancelled()) { if (currentTask != null && !currentTask.isCancelled()) {
if (currentTask instanceof YoutubeVideoTask) { if (currentTask instanceof YoutubeVideoTask) {

View file

@ -487,10 +487,10 @@ public class DialogsActivity extends BaseFragment implements NotificationCenter.
private boolean afterSignup; private boolean afterSignup;
private boolean showSetPasswordConfirm; private boolean showSetPasswordConfirm;
private int otherwiseReloginDays; private int otherwiseReloginDays;
private boolean allowGroups, allowMegagroups, allowLegacyGroups; public boolean allowGroups, allowMegagroups, allowLegacyGroups;
private boolean allowChannels; public boolean allowChannels;
private boolean allowUsers; public boolean allowUsers;
private boolean allowBots; public boolean allowBots;
private boolean closeFragment; private boolean closeFragment;
private FrameLayout updateLayout; private FrameLayout updateLayout;
@ -3028,7 +3028,7 @@ public class DialogsActivity extends BaseFragment implements NotificationCenter.
return !actionBar.isActionModeShowed() && databaseMigrationHint == null;// && !rightSlidingDialogContainer.hasFragment(); return !actionBar.isActionModeShowed() && databaseMigrationHint == null;// && !rightSlidingDialogContainer.hasFragment();
} }
}); });
if (initialDialogsType == DIALOGS_TYPE_ADD_USERS_TO || initialDialogsType == DIALOGS_TYPE_START_ATTACH_BOT || isArchive() && getDialogsArray(currentAccount, initialDialogsType, folderId, false).isEmpty()) { if (initialDialogsType == DIALOGS_TYPE_ADD_USERS_TO || isArchive() && getDialogsArray(currentAccount, initialDialogsType, folderId, false).isEmpty()) {
searchItem.setVisibility(View.GONE); searchItem.setVisibility(View.GONE);
} }
if (isArchive()) { if (isArchive()) {
@ -6437,7 +6437,11 @@ public class DialogsActivity extends BaseFragment implements NotificationCenter.
} }
}); });
if (showDialog(sheet) == null) { if (showDialog(sheet) == null) {
try {
sheet.show(); sheet.show();
} catch (Throwable throwable) {
FileLog.e(throwable);
}
} }
} else if (hasNotContactsPermission && askAboutContacts && getUserConfig().syncContacts && activity.shouldShowRequestPermissionRationale(Manifest.permission.READ_CONTACTS)) { } else if (hasNotContactsPermission && askAboutContacts && getUserConfig().syncContacts && activity.shouldShowRequestPermissionRationale(Manifest.permission.READ_CONTACTS)) {
AlertDialog.Builder builder = AlertsCreator.createContactsPermissionDialog(activity, param -> { AlertDialog.Builder builder = AlertsCreator.createContactsPermissionDialog(activity, param -> {

View file

@ -3694,7 +3694,11 @@ public class LaunchActivity extends BasePermissionsActivity implements INavigati
TLRPC.TL_attachMenuBotsBot attachMenuBotsBot = (TLRPC.TL_attachMenuBotsBot) response1; TLRPC.TL_attachMenuBotsBot attachMenuBotsBot = (TLRPC.TL_attachMenuBotsBot) response1;
MessagesController.getInstance(intentAccount).putUsers(attachMenuBotsBot.users, false); MessagesController.getInstance(intentAccount).putUsers(attachMenuBotsBot.users, false);
TLRPC.TL_attachMenuBot attachMenuBot = attachMenuBotsBot.bot; TLRPC.TL_attachMenuBot attachMenuBot = attachMenuBotsBot.bot;
BaseFragment lastFragment = mainFragmentsStack.get(mainFragmentsStack.size() - 1); BaseFragment lastFragment_ = mainFragmentsStack.get(mainFragmentsStack.size() - 1);
if (AndroidUtilities.isTablet() && !(lastFragment_ instanceof ChatActivity) && !rightFragmentsStack.isEmpty()) {
lastFragment_ = rightFragmentsStack.get(rightFragmentsStack.size() - 1);
}
final BaseFragment lastFragment = lastFragment_;
List<String> chooserTargets = new ArrayList<>(); List<String> chooserTargets = new ArrayList<>();
if (!TextUtils.isEmpty(attachMenuBotChoose)) { if (!TextUtils.isEmpty(attachMenuBotChoose)) {

View file

@ -1128,6 +1128,7 @@ public class PaymentFormActivity extends BaseFragment implements NotificationCen
progressView.setVisibility(View.VISIBLE); progressView.setVisibility(View.VISIBLE);
doneItem.setEnabled(false); doneItem.setEnabled(false);
doneItem.getContentView().setVisibility(View.INVISIBLE); doneItem.getContentView().setVisibility(View.INVISIBLE);
AndroidUtilities.checkAndroidTheme(context, true);
webView = new WebView(context) { webView = new WebView(context) {
@Override @Override
public boolean onTouchEvent(MotionEvent event) { public boolean onTouchEvent(MotionEvent event) {
@ -2336,6 +2337,7 @@ public class PaymentFormActivity extends BaseFragment implements NotificationCen
doneItem.setEnabled(false); doneItem.setEnabled(false);
doneItem.getContentView().setVisibility(View.INVISIBLE); doneItem.getContentView().setVisibility(View.INVISIBLE);
AndroidUtilities.checkAndroidTheme(context, true);
webView = new WebView(context) { webView = new WebView(context) {
@Override @Override
public boolean onTouchEvent(MotionEvent event) { public boolean onTouchEvent(MotionEvent event) {
@ -3096,6 +3098,7 @@ public class PaymentFormActivity extends BaseFragment implements NotificationCen
if (delegate != null) { if (delegate != null) {
delegate.onFragmentDestroyed(); delegate.onFragmentDestroyed();
} }
AndroidUtilities.checkAndroidTheme(getContext(), false);
if (!paymentStatusSent) { if (!paymentStatusSent) {
invoiceStatus = InvoiceStatus.CANCELLED; invoiceStatus = InvoiceStatus.CANCELLED;
if (paymentFormCallback != null && getOtherSameFragmentDiff() == 0) { if (paymentFormCallback != null && getOtherSameFragmentDiff() == 0) {

View file

@ -4442,7 +4442,7 @@ public class SelectAnimatedEmojiDialog extends FrameLayout implements Notificati
@Override @Override
protected boolean isTabIconsAnimationEnabled(boolean loaded) { protected boolean isTabIconsAnimationEnabled(boolean loaded) {
return LiteMode.isEnabled(LiteMode.FLAG_ANIMATED_EMOJI_KEYBOARD) && (!loaded || type == TYPE_AVATAR_CONSTRUCTOR); return LiteMode.isEnabled(LiteMode.FLAG_ANIMATED_EMOJI_KEYBOARD) || type == TYPE_AVATAR_CONSTRUCTOR;
} }
}; };
categoriesListView.setShownButtonsAtStart(type == TYPE_AVATAR_CONSTRUCTOR ? 6.5f : 4.5f); categoriesListView.setShownButtonsAtStart(type == TYPE_AVATAR_CONSTRUCTOR ? 6.5f : 4.5f);

View file

@ -3679,6 +3679,9 @@ public class PeerStoriesView extends SizeNotifierFrameLayout implements Notifica
} }
return true; return true;
} else if (getKeyboardHeight() >= AndroidUtilities.dp(20)) { } else if (getKeyboardHeight() >= AndroidUtilities.dp(20)) {
if (chatActivityEnterView != null) {
storyViewer.saveDraft(dialogId, currentStory.storyItem, chatActivityEnterView.getEditText());
}
AndroidUtilities.hideKeyboard(chatActivityEnterView); AndroidUtilities.hideKeyboard(chatActivityEnterView);
return true; return true;
} else if (storyCaptionView.getVisibility() == View.VISIBLE && storyCaptionView.getProgressToBlackout() > 0) { } else if (storyCaptionView.getVisibility() == View.VISIBLE && storyCaptionView.getProgressToBlackout() > 0) {
@ -4556,8 +4559,10 @@ public class PeerStoriesView extends SizeNotifierFrameLayout implements Notifica
checkReactionsLayout(); checkReactionsLayout();
ReactionsEffectOverlay.dismissAll(); ReactionsEffectOverlay.dismissAll();
} else { } else {
if (chatActivityEnterView != null) {
storyViewer.saveDraft(dialogId, currentStory.storyItem, chatActivityEnterView.getEditText()); storyViewer.saveDraft(dialogId, currentStory.storyItem, chatActivityEnterView.getEditText());
} }
}
if (keyboardVisible && mentionContainer != null) { if (keyboardVisible && mentionContainer != null) {
mentionContainer.setVisibility(View.VISIBLE); mentionContainer.setVisibility(View.VISIBLE);
} }

View file

@ -1999,7 +1999,7 @@ public class StoryRecorder implements NotificationCenter.NotificationCenterDeleg
try { try {
Long userId = Long.parseLong(span.getURL()); Long userId = Long.parseLong(span.getURL());
TLRPC.User user = MessagesController.getInstance(currentAccount).getUser(userId); TLRPC.User user = MessagesController.getInstance(currentAccount).getUser(userId);
if (user != null && UserObject.getPublicUsername(user) != null && !users.contains(user)) { if (user != null && !UserObject.isUserSelf(user) && UserObject.getPublicUsername(user) != null && !users.contains(user)) {
users.add(UserObject.getPublicUsername(user)); users.add(UserObject.getPublicUsername(user));
} }
} catch (Exception ignore) {} } catch (Exception ignore) {}
@ -2016,7 +2016,7 @@ public class StoryRecorder implements NotificationCenter.NotificationCenterDeleg
if (u != -1) { if (u != -1) {
String username = caption.subSequence(u, i).toString(); String username = caption.subSequence(u, i).toString();
TLObject obj = MessagesController.getInstance(currentAccount).getUserOrChat(username); TLObject obj = MessagesController.getInstance(currentAccount).getUserOrChat(username);
if (obj instanceof TLRPC.User && !((TLRPC.User) obj).bot && ((TLRPC.User) obj).id != 777000 && !UserObject.isReplyUser((TLRPC.User) obj) && !users.contains(username)) { if (obj instanceof TLRPC.User && !((TLRPC.User) obj).bot && !UserObject.isUserSelf((TLRPC.User) obj) && ((TLRPC.User) obj).id != 777000 && !UserObject.isReplyUser((TLRPC.User) obj) && !users.contains(username)) {
users.add(username); users.add(username);
} }
} }
@ -2026,7 +2026,7 @@ public class StoryRecorder implements NotificationCenter.NotificationCenterDeleg
if (u != -1) { if (u != -1) {
String username = caption.subSequence(u, caption.length()).toString(); String username = caption.subSequence(u, caption.length()).toString();
TLObject obj = MessagesController.getInstance(currentAccount).getUserOrChat(username); TLObject obj = MessagesController.getInstance(currentAccount).getUserOrChat(username);
if (obj instanceof TLRPC.User && !((TLRPC.User) obj).bot && ((TLRPC.User) obj).id != 777000 && !UserObject.isReplyUser((TLRPC.User) obj) && !users.contains(username)) { if (obj instanceof TLRPC.User && !((TLRPC.User) obj).bot && !UserObject.isUserSelf((TLRPC.User) obj) && ((TLRPC.User) obj).id != 777000 && !UserObject.isReplyUser((TLRPC.User) obj) && !users.contains(username)) {
users.add(username); users.add(username);
} }
} }

View file

@ -136,6 +136,7 @@ public class WebviewActivity extends BaseFragment {
@Override @Override
public void onFragmentDestroy() { public void onFragmentDestroy() {
super.onFragmentDestroy(); super.onFragmentDestroy();
AndroidUtilities.checkAndroidTheme(getContext(), false);
AndroidUtilities.cancelRunOnUIThread(typingRunnable); AndroidUtilities.cancelRunOnUIThread(typingRunnable);
webView.setLayerType(View.LAYER_TYPE_NONE, null); webView.setLayerType(View.LAYER_TYPE_NONE, null);
typingRunnable = null; typingRunnable = null;
@ -207,6 +208,7 @@ public class WebviewActivity extends BaseFragment {
progressItem.setEnabled(false); progressItem.setEnabled(false);
} }
AndroidUtilities.checkAndroidTheme(context, true);
webView = new WebView(context); webView = new WebView(context);
webView.getSettings().setJavaScriptEnabled(true); webView.getSettings().setJavaScriptEnabled(true);
webView.getSettings().setDomStorageEnabled(true); webView.getSettings().setDomStorageEnabled(true);

View file

@ -25,6 +25,20 @@
<item name="android:textViewStyle">@style/MyTextViewStyle</item> <item name="android:textViewStyle">@style/MyTextViewStyle</item>
</style> </style>
<style name="Theme.TMessages.Dark" parent="@android:style/Theme.Holo">
<item name="android:windowActionBar">false</item>
<item name="android:windowNoTitle">true</item>
<item name="android:windowActionBarOverlay">false</item>
<item name="android:windowContentOverlay">@null</item>
<item name="android:colorBackground">@android:color/black</item>
<item name="android:windowBackground">@android:color/black</item>
<item name="android:itemTextAppearance">@style/ActionBar.Transparent.TMessages.Item</item>
<item name="android:listViewStyle">@style/Theme.TMessages.ListView</item>
<item name="android:listChoiceBackgroundIndicator">@drawable/list_selector_ex</item>
<item name="android:actionBarItemBackground">@drawable/bar_selector_style</item>
<item name="android:textViewStyle">@style/MyTextViewStyle</item>
</style>
<style name="Theme.TMessages.PopupNotification" parent="Theme.TMessages"> <style name="Theme.TMessages.PopupNotification" parent="Theme.TMessages">
<item name="android:windowBackground">@android:color/transparent</item> <item name="android:windowBackground">@android:color/transparent</item>
<item name="android:windowIsTranslucent">true</item> <item name="android:windowIsTranslucent">true</item>

View file

@ -13,8 +13,8 @@
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true # org.gradle.parallel=true
#Sat Mar 12 05:53:50 MSK 2016 #Sat Mar 12 05:53:50 MSK 2016
APP_VERSION_CODE=3801 APP_VERSION_CODE=3802
APP_VERSION_NAME=10.0.3 APP_VERSION_NAME=10.0.4
APP_PACKAGE=org.telegram.messenger APP_PACKAGE=org.telegram.messenger
RELEASE_KEY_PASSWORD=android RELEASE_KEY_PASSWORD=android
RELEASE_KEY_ALIAS=androidkey RELEASE_KEY_ALIAS=androidkey