1 /* 2 * Copyright 2019 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package com.android.angle.common; 17 18 import android.content.BroadcastReceiver; 19 import android.content.Context; 20 import android.content.Intent; 21 import android.content.SharedPreferences; 22 import android.database.ContentObserver; 23 import android.net.Uri; 24 import android.os.Bundle; 25 import android.os.Handler; 26 import android.provider.Settings; 27 import android.text.TextUtils; 28 import android.util.Log; 29 30 import androidx.preference.PreferenceManager; 31 32 import org.json.JSONArray; 33 import org.json.JSONException; 34 import org.json.JSONObject; 35 36 import java.io.IOException; 37 import java.io.InputStream; 38 import java.util.Collections; 39 import java.util.List; 40 import java.util.stream.Collectors; 41 import java.util.stream.Stream; 42 43 import com.android.angle.R; 44 45 public class Receiver extends BroadcastReceiver 46 { 47 private static final String TAG = "AngleBroadcastReceiver"; 48 private static final boolean DEBUG = false; 49 50 @Override onReceive(Context context, Intent intent)51 public void onReceive(Context context, Intent intent) 52 { 53 final String action = intent.getAction(); 54 if (DEBUG) 55 { 56 Log.d(TAG, "Received intent: " + action); 57 } 58 59 if (action.equals(context.getString(R.string.intent_angle_for_android_toast_message))) 60 { 61 Bundle results = getResultExtras(true); 62 results.putString(context.getString(R.string.intent_key_a4a_toast_message), 63 context.getString(R.string.angle_in_use_toast_message)); 64 } 65 else if (action.equals(Intent.ACTION_BOOT_COMPLETED) || action.equals(Intent.ACTION_MY_PACKAGE_REPLACED)) 66 { 67 AngleRuleHelper angleRuleHelper = new AngleRuleHelper(context); 68 updateGlobalSettings(context, angleRuleHelper); 69 updateDeveloperOptionsWatcher(context); 70 } 71 } 72 73 /** 74 * Consume the results of rule parsing to populate global settings 75 */ updateGlobalSettings(Context context, AngleRuleHelper angleRuleHelper)76 private static void updateGlobalSettings(Context context, AngleRuleHelper angleRuleHelper) 77 { 78 int count = 0; 79 String packages = ""; 80 String choices = ""; 81 82 // Bring in the packages and choices and convert them to global settings format 83 final List<String> anglePackages = angleRuleHelper.getPackageNamesForAngle(); 84 final List<String> nativePackages = angleRuleHelper.getPackageNamesForNative(); 85 86 // packages = anglePackage1,anglePackage2,nativePackage1,nativePackage2 87 packages = Stream.concat(anglePackages.stream(), nativePackages.stream()) 88 .collect(Collectors.joining(",")); 89 90 // choices = angle,angle,native,native 91 choices = Stream.concat( 92 Collections.nCopies( 93 anglePackages.size(), "angle") 94 .stream(), 95 Collections.nCopies( 96 nativePackages.size(), "native") 97 .stream()) 98 .collect(Collectors.joining(",")); 99 100 Log.v(TAG, "Updating ANGLE global settings with:" + 101 " packages = " + packages + 102 " choices = " + choices); 103 GlobalSettings.writeGlobalSettings(context, packages, choices); 104 } 105 106 /** 107 * When Developer Options are disabled, reset all of the global settings back to their defaults. 108 */ updateDeveloperOptionsWatcher(Context context)109 private static void updateDeveloperOptionsWatcher(Context context) 110 { 111 final Uri settingUri = Settings.Global.getUriFor(Settings.Global.DEVELOPMENT_SETTINGS_ENABLED); 112 113 final ContentObserver developerOptionsObserver = new ContentObserver(new Handler()) { 114 @Override 115 public void onChange(boolean selfChange) 116 { 117 super.onChange(selfChange); 118 119 final boolean developerOptionsEnabled = 120 (1 121 == Settings.Global.getInt(context.getContentResolver(), 122 Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0)); 123 124 Log.v(TAG, "Developer Options enabled value changed: " 125 + "developerOptionsEnabled = " + developerOptionsEnabled); 126 127 if (!developerOptionsEnabled) 128 { 129 // Reset the necessary settings to their defaults. 130 SharedPreferences.Editor editor = 131 PreferenceManager.getDefaultSharedPreferences(context).edit(); 132 editor.clear(); 133 editor.apply(); 134 GlobalSettings.clearGlobalSettings(context); 135 } 136 } 137 }; 138 139 context.getContentResolver().registerContentObserver( 140 settingUri, false, developerOptionsObserver); 141 } 142 } 143