Skip to content

Commit f300cb0

Browse files
committed
json-rebranding and campaign-install
1 parent c0ea24f commit f300cb0

File tree

15 files changed

+573
-13
lines changed

15 files changed

+573
-13
lines changed

src/build/config/android/config.gni

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -225,10 +225,10 @@ if (is_android || is_chromeos) {
225225

226226
# Forced Android versionCode
227227

228-
android_override_version_code = "100"
228+
android_override_version_code = "102"
229229

230230
# Forced Android versionName
231-
android_override_version_name = "0.82"
231+
android_override_version_name = "0.84"
232232

233233
# The path to the keystore to use for signing builds.
234234
android_keystore_path = default_android_keystore_path

src/chrome/android/chrome_java_sources.gni

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ chrome_java_sources = [
1313
"java/src/org/chromium/chrome/browser/AppIndexingUtil.java",
1414
"java/src/org/chromium/chrome/browser/ApplicationLifetime.java",
1515
"java/src/org/chromium/chrome/browser/BackupSigninProcessor.java",
16+
"java/src/org/chromium/chrome/browser/BrandingManager.java",
1617
"java/src/org/chromium/chrome/browser/BrowserRestartActivity.java",
1718
"java/src/org/chromium/chrome/browser/WootzDialogFragment.java",
1819
"java/src/org/chromium/chrome/browser/ChromeActionModeHandler.java",

src/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/IncognitoReauthPromoViewModel.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,11 @@
88
import static org.chromium.chrome.browser.tasks.tab_management.TabListModel.CardProperties.CARD_TYPE;
99

1010
import android.content.Context;
11+
import android.content.SharedPreferences;
1112

1213
import androidx.appcompat.content.res.AppCompatResources;
1314

15+
import org.chromium.base.ContextUtils;
1416
import org.chromium.base.metrics.RecordHistogram;
1517
import org.chromium.chrome.tab_ui.R;
1618
import org.chromium.ui.modelutil.PropertyModel;
@@ -29,7 +31,17 @@ public static PropertyModel create(
2931
Context context,
3032
MessageCardView.DismissActionProvider uiDismissActionProvider,
3133
IncognitoReauthPromoMessageService.IncognitoReauthMessageData data) {
34+
35+
// Get dynamic app name for branding
36+
String appName = ContextUtils.getAppSharedPreferences().getString("app_name", "Browser");
37+
boolean hasCustomBranding = !appName.equals("Browser");
38+
39+
// Get title text and make it dynamic
3240
String titleText = context.getString(R.string.incognito_reauth_promo_title);
41+
if (hasCustomBranding && titleText.contains("WootzApp")) {
42+
titleText = titleText.replace("WootzApp", appName);
43+
}
44+
3345
String descriptionText = context.getString(R.string.incognito_reauth_promo_description);
3446
String actionText = context.getString(R.string.incognito_reauth_lock_action_text);
3547
String dismissActionText = context.getString(R.string.no_thanks);

src/chrome/android/java/res/xml/developer_preferences.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ found in the LICENSE file.
1717
android:layout_height="wrap_content"
1818
android:enabled="false"
1919
android:key="beta_stable_hint"
20-
android:title="Hint: You can also enable Developer options on Beta/Stable channels by tapping the Chrome version in "Settings > About WootzApp" multiple times."
20+
android:title="Hint: You can also enable Developer options on Beta/Stable channels by tapping the version in "Settings > About" multiple times."
2121
app:allowDividerAbove="false"
2222
app:allowDividerBelow="false" />
2323
</PreferenceScreen>
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
package org.chromium.chrome.browser;
2+
3+
import androidx.annotation.NonNull;
4+
import androidx.annotation.Nullable;
5+
6+
import org.json.JSONObject;
7+
8+
public class BrandingConfig {
9+
private String utmSource;
10+
private String appName;
11+
private String iconUrl;
12+
private String packageName;
13+
private String primaryColor;
14+
private String accentColor;
15+
16+
public BrandingConfig() {}
17+
18+
public static BrandingConfig fromJson(JSONObject json) {
19+
BrandingConfig config = new BrandingConfig();
20+
config.utmSource = json.optString("utmSource", "");
21+
config.appName = json.optString("appName", "");
22+
config.iconUrl = json.optString("iconUrl", "");
23+
config.packageName = json.optString("packageName", "");
24+
config.primaryColor = json.optString("primaryColor", "");
25+
config.accentColor = json.optString("accentColor", "");
26+
return config;
27+
}
28+
29+
public JSONObject toJson() {
30+
JSONObject json = new JSONObject();
31+
try {
32+
json.put("utmSource", utmSource);
33+
json.put("appName", appName);
34+
json.put("iconUrl", iconUrl);
35+
json.put("packageName", packageName);
36+
json.put("primaryColor", primaryColor);
37+
json.put("accentColor", accentColor);
38+
} catch (Exception e) {
39+
// Handle JSON exception
40+
}
41+
return json;
42+
}
43+
44+
// Getters and setters
45+
@NonNull
46+
public String getUtmSource() { return utmSource; }
47+
public void setUtmSource(String utmSource) { this.utmSource = utmSource; }
48+
49+
@NonNull
50+
public String getAppName() { return appName; }
51+
public void setAppName(String appName) { this.appName = appName; }
52+
53+
@Nullable
54+
public String getIconUrl() { return iconUrl; }
55+
public void setIconUrl(String iconUrl) { this.iconUrl = iconUrl; }
56+
57+
@NonNull
58+
public String getPackageName() { return packageName; }
59+
public void setPackageName(String packageName) { this.packageName = packageName; }
60+
61+
@Nullable
62+
public String getPrimaryColor() { return primaryColor; }
63+
public void setPrimaryColor(String primaryColor) { this.primaryColor = primaryColor; }
64+
65+
@Nullable
66+
public String getAccentColor() { return accentColor; }
67+
public void setAccentColor(String accentColor) { this.accentColor = accentColor; }
68+
}
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
// BrandingManager.java
2+
package org.chromium.chrome.browser;
3+
4+
import android.content.SharedPreferences;
5+
import android.text.TextUtils;
6+
import android.util.Log;
7+
import android.widget.ImageView;
8+
import android.widget.TextView;
9+
10+
import androidx.annotation.NonNull;
11+
import androidx.annotation.Nullable;
12+
13+
import org.chromium.base.ContextUtils;
14+
import org.chromium.base.task.AsyncTask;
15+
import org.chromium.chrome.R;
16+
import org.json.JSONArray;
17+
import org.json.JSONObject;
18+
19+
import java.io.InputStream;
20+
import java.net.HttpURLConnection;
21+
import java.net.URL;
22+
import java.util.Scanner;
23+
24+
public class BrandingManager {
25+
private static final String TAG = "BrandingManager";
26+
27+
// GitHub URL - using your actual repository
28+
private static final String GITHUB_URL = "https://raw.githubusercontent.com/1311-hack1/rebrand/main/branding.json";
29+
30+
// Simple keys
31+
private static final String KEY_APP_NAME = "app_name";
32+
private static final String KEY_UTM = "utm_source";
33+
private static final String KEY_ICON_URL = "icon_url";
34+
35+
/**
36+
* One simple method - fetch from GitHub and save.
37+
* Call this when you get a UTM source.
38+
*/
39+
public static void fetchAndSave(String utmSource) {
40+
Log.e(TAG, "fetchAndSave: " + utmSource);
41+
if (TextUtils.isEmpty(utmSource)) return;
42+
43+
new AsyncTask<Void>() {
44+
@Override
45+
protected Void doInBackground() {
46+
Log.e(TAG, "doInBackground: " + utmSource);
47+
try {
48+
// Get JSON from GitHub
49+
URL url = new URL(GITHUB_URL);
50+
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
51+
InputStream input = conn.getInputStream();
52+
Scanner scanner = new Scanner(input).useDelimiter("\\A");
53+
String json = scanner.hasNext() ? scanner.next() : "";
54+
conn.disconnect();
55+
Log.e(TAG, "json: " + json);
56+
// Parse and find matching UTM
57+
JSONArray brands = new JSONObject(json).getJSONArray("brands");
58+
for (int i = 0; i < brands.length(); i++) {
59+
JSONObject brand = brands.getJSONObject(i);
60+
if (utmSource.equals(brand.optString("utmSource"))) {
61+
// Save to preferences
62+
String appName = brand.optString("appName", "Browser");
63+
String iconUrl = brand.optString("iconUrl", "");
64+
ContextUtils.getAppSharedPreferences().edit()
65+
.putString(KEY_APP_NAME, appName)
66+
.putString(KEY_UTM, utmSource)
67+
.putString(KEY_ICON_URL, iconUrl)
68+
.apply();
69+
Log.e(TAG, "Saved: " + appName);
70+
Log.e(TAG, "Saved: " + utmSource);
71+
Log.e(TAG, "Saved icon URL: " + iconUrl);
72+
break;
73+
}
74+
}
75+
} catch (Exception e) {
76+
Log.e(TAG, "Error fetching branding", e);
77+
}
78+
return null;
79+
}
80+
81+
@Override
82+
protected void onPostExecute(Void result) {
83+
// This method is required but we don't need to do anything here
84+
// since we're not updating UI from this task
85+
}
86+
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
87+
}
88+
89+
/**
90+
* Get current app name.
91+
*/
92+
@NonNull
93+
public static String getAppName() {
94+
return ContextUtils.getAppSharedPreferences().getString(KEY_APP_NAME, "Browser");
95+
}
96+
97+
/**
98+
* Set app name in TextView.
99+
*/
100+
public static void setTitle(@Nullable TextView textView) {
101+
if (textView != null) textView.setText(getAppName());
102+
}
103+
104+
/**
105+
* Set settings title in TextView.
106+
*/
107+
public static void setSettingsTitle(@Nullable TextView textView) {
108+
if (textView != null) textView.setText(getAppName() + " Settings");
109+
}
110+
111+
/**
112+
* Set incognito title in TextView.
113+
*/
114+
public static void setIncognitoTitle(@Nullable TextView textView) {
115+
if (textView != null) textView.setText(getAppName() + " Incognito");
116+
}
117+
118+
/**
119+
* Set default icon in ImageView.
120+
*/
121+
public static void setIcon(@Nullable ImageView imageView) {
122+
if (imageView != null) imageView.setImageResource(R.drawable.ic_chrome);
123+
}
124+
}

src/chrome/android/java/src/org/chromium/chrome/browser/about_settings/AboutChromeSettings.java

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,13 @@
99
import android.content.pm.PackageManager.NameNotFoundException;
1010
import android.os.Bundle;
1111
import android.text.format.DateUtils;
12+
import android.text.TextUtils;
13+
import android.util.Log;
1214

1315
import androidx.preference.Preference;
1416
import androidx.preference.PreferenceFragmentCompat;
1517

18+
import org.chromium.base.ContextUtils;
1619
import org.chromium.base.version_info.VersionInfo;
1720
import org.chromium.chrome.R;
1821
import org.chromium.chrome.browser.tracing.settings.DeveloperSettings;
@@ -45,7 +48,8 @@ public class AboutChromeSettings extends PreferenceFragmentCompat
4548

4649
@Override
4750
public void onCreatePreferences(Bundle bundle, String s) {
48-
getActivity().setTitle(R.string.prefs_about_wootzapp);
51+
// Set dynamic title based on branding
52+
setDynamicTitle();
4953
SettingsUtils.addPreferencesFromResource(this, R.xml.about_wootzapp_preferences);
5054

5155
Preference p = findPreference(PREF_APPLICATION_VERSION);
@@ -59,11 +63,42 @@ public void onCreatePreferences(Bundle bundle, String s) {
5963
p.setSummary(getString(R.string.legal_information_summary, currentYear));
6064
}
6165

66+
/**
67+
* Set dynamic title based on current branding.
68+
*/
69+
private void setDynamicTitle() {
70+
// Read app name from SharedPreferences (same as BrandingManager)
71+
String appName = ContextUtils.getAppSharedPreferences().getString("app_name", "Browser");
72+
boolean hasCustomBranding = !appName.equals("Browser");
73+
Log.e("AboutChromeSettings", "setDynamicTitle: appName = " + appName);
74+
75+
if (hasCustomBranding) {
76+
// Create dynamic title: "About [AppName]"
77+
Log.e("AboutChromeSettings", "setDynamicTitle: hasCustomBranding = " + hasCustomBranding);
78+
String dynamicTitle = getString(R.string.prefs_about_wootzapp)
79+
.replace("WootzApp", appName);
80+
Log.e("AboutChromeSettings", "setDynamicTitle: dynamicTitle = " + dynamicTitle);
81+
getActivity().setTitle(dynamicTitle);
82+
} else {
83+
// Use original title
84+
getActivity().setTitle(R.string.prefs_about_wootzapp);
85+
}
86+
}
87+
6288
/**
6389
* Build the application version to be shown. In particular, this ensures the debug build
6490
* versions are more useful.
6591
*/
6692
public static String getApplicationVersion(Context context, String version) {
93+
// Get dynamic app name for branding
94+
String appName = ContextUtils.getAppSharedPreferences().getString("app_name", "Browser");
95+
boolean hasCustomBranding = !appName.equals("Browser");
96+
97+
// Replace "WootzApp" in version string with custom app name if needed
98+
if (hasCustomBranding && version.contains("WootzApp")) {
99+
version = version.replace("WootzApp", appName);
100+
}
101+
67102
if (VersionInfo.isOfficialBuild()) {
68103
return version;
69104
}
@@ -78,7 +113,15 @@ public static String getApplicationVersion(Context context, String version) {
78113
CharSequence updateTimeString =
79114
DateUtils.getRelativeTimeSpanString(
80115
info.lastUpdateTime, System.currentTimeMillis(), 0);
81-
return context.getString(R.string.version_with_update_time, version, updateTimeString);
116+
117+
String finalVersionString = context.getString(R.string.version_with_update_time, version, updateTimeString);
118+
119+
// Also replace "WootzApp" in the final string if it exists
120+
if (hasCustomBranding && finalVersionString.contains("WootzApp")) {
121+
finalVersionString = finalVersionString.replace("WootzApp", appName);
122+
}
123+
124+
return finalVersionString;
82125
}
83126

84127
@Override

src/chrome/android/java/src/org/chromium/chrome/browser/homepage/settings/RadioButtonGroupHomepagePreference.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import org.chromium.components.browser_ui.widget.RadioButtonWithDescriptionLayout;
2222
import org.chromium.components.browser_ui.widget.RadioButtonWithEditText;
2323
import org.chromium.components.browser_ui.widget.RadioButtonWithEditText.OnTextChangeListener;
24+
import org.chromium.base.ContextUtils;
2425

2526
import java.lang.annotation.Retention;
2627
import java.lang.annotation.RetentionPolicy;
@@ -153,6 +154,9 @@ public void onBindViewHolder(PreferenceViewHolder holder) {
153154

154155
mTitle = (TextView) holder.findViewById(R.id.title);
155156

157+
// Update Chrome NTP radio button text dynamically based on branding
158+
updateChromeNtpText();
159+
156160
mIsBoundToViewHolder = true;
157161
// Set up views with data provided by the delegate.
158162
if (mPreferenceValues != null) {
@@ -227,4 +231,22 @@ RadioButtonWithDescription getChromeNtpRadioButton() {
227231
TextView getTitleTextView() {
228232
return mTitle;
229233
}
234+
235+
private void updateChromeNtpText() {
236+
if (mChromeNtp == null) return;
237+
238+
// Get the custom app name from SharedPreferences
239+
String appName = ContextUtils.getAppSharedPreferences().getString("app_name", "Browser");
240+
boolean hasCustomBranding = !appName.equals("Browser");
241+
242+
if (hasCustomBranding) {
243+
// Get the original string and replace "WootzApp" with custom app name
244+
String originalText = getContext().getString(R.string.options_homepage_wootzapp_homepage);
245+
String dynamicText = originalText.replace("WootzApp", appName);
246+
mChromeNtp.setPrimaryText(dynamicText);
247+
} else {
248+
// Use original text
249+
mChromeNtp.setPrimaryText(getContext().getString(R.string.options_homepage_wootzapp_homepage));
250+
}
251+
}
230252
}

0 commit comments

Comments
 (0)