diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index f3b3d2daf434e636eb5044c138fc281631d8a657..5fa284cdd01bf89e6d5cc9cb2a078be5292e93a2 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -3408,6 +3408,12 @@
+
+
+ Use staging OTA server
+ Change to OTA/Production server
+
Development tools
diff --git a/res/xml/development_settings.xml b/res/xml/development_settings.xml
index 8a8d2d4defa34ae26a38867915d25b9effa85dd0..44715847366c04327339fc0e6a92494d252c2201 100644
--- a/res/xml/development_settings.xml
+++ b/res/xml/development_settings.xml
@@ -574,6 +574,11 @@
android:title="@string/kill_app_longpress_back"
android:summary="@string/kill_app_longpress_back_summary"
android:defaultValue="false" />
+
+
diff --git a/src/com/android/settings/development/ChangeSourcePreferenceController.java b/src/com/android/settings/development/ChangeSourcePreferenceController.java
new file mode 100644
index 0000000000000000000000000000000000000000..7aa070378b70d63fa548b829e0094eb6ee507ec7
--- /dev/null
+++ b/src/com/android/settings/development/ChangeSourcePreferenceController.java
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2021 ECORP SAS
+ *
+ * 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.android.settings.development;
+
+import android.content.Context;
+import android.provider.Settings;
+import android.support.annotation.VisibleForTesting;
+import android.support.v14.preference.SwitchPreference;
+import android.support.v7.preference.Preference;
+import android.preference.PreferenceManager;
+import android.content.SharedPreferences;
+import android.content.ContentValues;
+import android.database.Cursor;
+import android.net.Uri;
+import android.content.Context;
+
+import com.android.settings.core.PreferenceControllerMixin;
+import com.android.settingslib.development.DeveloperOptionsPreferenceController;
+
+public class ChangeSourcePreferenceController extends DeveloperOptionsPreferenceController implements
+ Preference.OnPreferenceChangeListener, PreferenceControllerMixin {
+
+ SharedPreferences preferences;
+ private static final String CHANGE_URL_KEY = "change_update_source";
+ private final String UPDATE_URI ="content://custom.setting.Provider.OTA_SERVER/cte";
+ private String status;
+
+ @VisibleForTesting
+ static final int SETTING_VALUE_ON = 1;
+ @VisibleForTesting
+ static final int SETTING_VALUE_OFF = 0;
+
+ public ChangeSourcePreferenceController(Context context) {
+ super(context);
+ }
+
+ @Override
+ public String getPreferenceKey() {
+ return CHANGE_URL_KEY;
+ }
+
+ @Override
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ final boolean isEnabled = (Boolean) newValue;
+ ((SwitchPreference) mPreference).setChecked(isEnabled);
+ if (count(OTAProvider.CONTENT_URI)) {
+ ContentValues values = new ContentValues();
+
+ if (retrieveStatus().equals("true")) {
+ values.put(OTAProvider.Status, "false");
+ mContext.getContentResolver().update(OTAProvider.CONTENT_URI, values, OTAProvider.id + "=?", new String[]{"1"});
+ }else{
+ values.put(OTAProvider.Status, "true");
+ mContext.getContentResolver().update(OTAProvider.CONTENT_URI, values, OTAProvider.id + "=?", new String[]{"1"});
+ }
+ } else {
+ ContentValues values = new ContentValues();
+ values.put(OTAProvider.Status,"true");
+ mContext.getContentResolver().insert(OTAProvider.CONTENT_URI, values);
+ }
+ return true;
+ }
+
+ @Override
+ public void updateState(Preference preference) {
+ if (retrieveStatus().equals("true")){
+ ((SwitchPreference) mPreference).setChecked(true);
+ }else{
+ ((SwitchPreference) mPreference).setChecked(false);
+ }
+ }
+
+ @Override
+ protected void onDeveloperOptionsSwitchDisabled() {
+ super.onDeveloperOptionsSwitchDisabled();
+ ((SwitchPreference) mPreference).setChecked(false);
+ }
+
+ @Override
+ protected void onDeveloperOptionsSwitchEnabled() {
+ super.onDeveloperOptionsSwitchEnabled();
+ if (!count(OTAProvider.CONTENT_URI)){
+ ContentValues values = new ContentValues();
+ values.put(OTAProvider.Status,"false");
+ mContext.getContentResolver().insert(OTAProvider.CONTENT_URI, values);
+ }
+
+ }
+
+ public boolean count(Uri uri) {
+ Cursor cursor = mContext.getContentResolver().query(uri, new String[]{"id"},
+ null, null, null);
+ if (cursor.getCount() > 0) {
+ return true;
+ }else {
+ return false;
+ }
+ }
+
+ private String retrieveStatus(){
+ Cursor cursor = mContext.getContentResolver().query(Uri.parse(UPDATE_URI), null, OTAProvider.id+"=?", new String[]{"1"}, OTAProvider.Status);
+ if (cursor.moveToFirst()) {
+ do {
+ status = cursor.getString(cursor.getColumnIndex(OTAProvider.Status));
+ } while (cursor.moveToNext());
+ }
+ return status;
+ }
+}
diff --git a/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java b/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java
index f2011bc612bbaa52626cafdb178717dd4826da4b..7ecc750dfba9e7bc9f6c20bc8620437a231869a0 100644
--- a/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java
+++ b/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2017 The Android Open Source Project
+ * Copyright (C) 2021 ECORP SAS
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -456,6 +457,7 @@ public class DevelopmentSettingsDashboardFragment extends RestrictedDashboardFra
bluetoothA2dpConfigStore));
controllers.add(new BluetoothMaxConnectedAudioDevicesPreferenceController(context));
controllers.add(new ShowTapsPreferenceController(context));
+ controllers.add(new ChangeSourcePreferenceController(context));
controllers.add(new PointerLocationPreferenceController(context));
controllers.add(new ShowSurfaceUpdatesPreferenceController(context));
controllers.add(new ShowLayoutBoundsPreferenceController(context));
diff --git a/src/com/android/settings/development/OTAProvider.java b/src/com/android/settings/development/OTAProvider.java
new file mode 100644
index 0000000000000000000000000000000000000000..30127bde361fe75c96bce0a2ade258049d08b4e1
--- /dev/null
+++ b/src/com/android/settings/development/OTAProvider.java
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) 2021 ECORP SAS
+ *
+ * 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.android.settings.development;
+
+import java.util.HashMap;
+
+import android.content.ContentProvider;
+import android.content.ContentUris;
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.UriMatcher;
+import android.database.Cursor;
+import android.database.SQLException;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteOpenHelper;
+import android.database.sqlite.SQLiteQueryBuilder;
+import android.net.Uri;
+
+public class OTAProvider extends ContentProvider {
+
+ static final String PROVIDER_NAME = "custom.setting.Provider.OTA_SERVER";
+ static final String URL = "content://" + PROVIDER_NAME + "/cte";
+ static final Uri CONTENT_URI = Uri.parse(URL);
+
+ static final String id = "id";
+ static final String Status = "Status";
+ static final int uriCode = 1;
+ static final UriMatcher uriMatcher;
+ private static HashMap values;
+ private SQLiteDatabase db;
+ static final String DATABASE_NAME = "mydb";
+ static final String TABLE_NAME = "ota";
+ static final int DATABASE_VERSION = 1;
+ static final String CREATE_DB_TABLE = " CREATE TABLE " + TABLE_NAME
+ + " (id INTEGER PRIMARY KEY AUTOINCREMENT, "
+ + " Status TEXT NOT NULL);";
+ static {
+ uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
+ uriMatcher.addURI(PROVIDER_NAME, "cte", uriCode);
+ uriMatcher.addURI(PROVIDER_NAME, "cte/*", uriCode);
+ }
+
+ @Override
+ public boolean onCreate() {
+ Context context = getContext();
+ DatabaseHelper dbHelper = new DatabaseHelper(context);
+ db = dbHelper.getWritableDatabase();
+ if (db != null) {
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public Cursor query(Uri uri, String[] projection, String selection,
+ String[] selectionArgs, String sortOrder) {
+ SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
+ qb.setTables(TABLE_NAME);
+
+ switch (uriMatcher.match(uri)) {
+ case uriCode:
+ qb.setProjectionMap(values);
+ break;
+ default:
+ throw new IllegalArgumentException("Unknown URI " + uri);
+ }
+ if (sortOrder == null || sortOrder == "") {
+ sortOrder = Status;
+ }
+ Cursor c = qb.query(db, projection, selection, selectionArgs, null,
+ null, sortOrder);
+ c.setNotificationUri(getContext().getContentResolver(), uri);
+ return c;
+ }
+
+
+ @Override
+ public String getType(Uri uri) {
+ switch (uriMatcher.match(uri)) {
+ case uriCode:
+ return "vnd.android.cursor.dir/cte";
+
+ default:
+ throw new IllegalArgumentException("Unsupported URI: " + uri);
+ }
+ }
+
+ @Override
+ public Uri insert(Uri uri, ContentValues values) {
+ long rowID = db.insert(TABLE_NAME, "", values);
+ if (rowID > 0) {
+ Uri _uri = ContentUris.withAppendedId(CONTENT_URI, rowID);
+ getContext().getContentResolver().notifyChange(_uri, null);
+ return _uri;
+ }
+ throw new SQLException("Failed to add a record into " + uri);
+ }
+
+ @Override
+ public int delete(Uri uri, String selection, String[] selectionArgs) {
+ int count = 0;
+ switch (uriMatcher.match(uri)) {
+ case uriCode:
+ count = db.delete(TABLE_NAME, selection, selectionArgs);
+ break;
+ default:
+ throw new IllegalArgumentException("Unknown URI " + uri);
+ }
+ getContext().getContentResolver().notifyChange(uri, null);
+ return count;
+ }
+
+ @Override
+ public int update(Uri uri, ContentValues values, String selection,
+ String[] selectionArgs) {
+ int count = 0;
+ switch (uriMatcher.match(uri)) {
+ case uriCode:
+ count = db.update(TABLE_NAME, values, selection, selectionArgs);
+ break;
+ default:
+ throw new IllegalArgumentException("Unknown URI " + uri);
+ }
+ getContext().getContentResolver().notifyChange(uri, null);
+ return count;
+ }
+
+
+ private static class DatabaseHelper extends SQLiteOpenHelper {
+ DatabaseHelper(Context context) {
+ super(context, DATABASE_NAME, null, DATABASE_VERSION);
+ }
+
+ @Override
+ public void onCreate(SQLiteDatabase db) {
+ db.execSQL(CREATE_DB_TABLE);
+ }
+
+ @Override
+ public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+ db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
+ onCreate(db);
+ }
+ }
+}