Home | History | Annotate | Download | only in facade
      1 /*
      2  * Copyright (C) 2017 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 
     17 package com.googlecode.android_scripting.facade;
     18 
     19 import android.app.AlarmManager;
     20 import android.app.NotificationManager;
     21 import android.app.Service;
     22 import android.app.admin.DevicePolicyManager;
     23 import android.content.Context;
     24 import android.content.Intent;
     25 import android.media.AudioManager;
     26 import android.os.PowerManager;
     27 import android.os.SystemClock;
     28 import android.os.UserHandle;
     29 import android.provider.Settings;
     30 import android.provider.Settings.SettingNotFoundException;
     31 import android.telephony.SubscriptionManager;
     32 import android.telephony.TelephonyManager;
     33 import android.view.WindowManager;
     34 
     35 import com.android.internal.widget.LockPatternUtils;
     36 
     37 import com.googlecode.android_scripting.BaseApplication;
     38 import com.googlecode.android_scripting.FutureActivityTaskExecutor;
     39 import com.googlecode.android_scripting.Log;
     40 import com.googlecode.android_scripting.future.FutureActivityTask;
     41 import com.googlecode.android_scripting.jsonrpc.RpcReceiver;
     42 import com.googlecode.android_scripting.rpc.Rpc;
     43 import com.googlecode.android_scripting.rpc.RpcDefault;
     44 import com.googlecode.android_scripting.rpc.RpcOptional;
     45 import com.googlecode.android_scripting.rpc.RpcParameter;
     46 
     47 /**
     48  * Exposes phone settings functionality.
     49  *
     50  */
     51 public class SettingsFacade extends RpcReceiver {
     52 
     53     private final Service mService;
     54     private final AndroidFacade mAndroidFacade;
     55     private final AudioManager mAudio;
     56     private final PowerManager mPower;
     57     private final AlarmManager mAlarm;
     58     private final LockPatternUtils mLockPatternUtils;
     59     private final NotificationManager mNotificationManager;
     60     private final DataUsageController mDataController;
     61     private final TelephonyManager mTelephonyManager;
     62 
     63     /**
     64      * Creates a new SettingsFacade.
     65      *
     66      * @param manager is the {@link Context} the APIs will run under
     67      */
     68     public SettingsFacade(FacadeManager manager) {
     69         super(manager);
     70         mService = manager.getService();
     71         mAndroidFacade = manager.getReceiver(AndroidFacade.class);
     72         mAudio = (AudioManager) mService.getSystemService(Context.AUDIO_SERVICE);
     73         mPower = (PowerManager) mService.getSystemService(Context.POWER_SERVICE);
     74         mAlarm = (AlarmManager) mService.getSystemService(Context.ALARM_SERVICE);
     75         mLockPatternUtils = new LockPatternUtils(mService);
     76         mNotificationManager =
     77             (NotificationManager) mService.getSystemService(Context.NOTIFICATION_SERVICE);
     78         if (!mNotificationManager.isNotificationPolicyAccessGranted()) {
     79             Intent intent = new Intent(Settings.ACTION_NOTIFICATION_POLICY_ACCESS_SETTINGS);
     80             intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
     81             mService.startActivity(intent);
     82         }
     83         mDataController = new DataUsageController(mService);
     84         mTelephonyManager =
     85                 (TelephonyManager) mService.getSystemService(Context.TELEPHONY_SERVICE);
     86     }
     87 
     88     @Rpc(description = "Sets the screen timeout to this number of seconds.",
     89             returns = "The original screen timeout.")
     90     public Integer setScreenTimeout(@RpcParameter(name = "value") Integer value) {
     91         Integer oldValue = getScreenTimeout();
     92         android.provider.Settings.System.putInt(mService.getContentResolver(),
     93                 android.provider.Settings.System.SCREEN_OFF_TIMEOUT, value * 1000);
     94         return oldValue;
     95     }
     96 
     97     @Rpc(description = "Returns the current screen timeout in seconds.",
     98             returns = "the current screen timeout in seconds.")
     99     public Integer getScreenTimeout() {
    100         try {
    101             return android.provider.Settings.System.getInt(mService.getContentResolver(),
    102                     android.provider.Settings.System.SCREEN_OFF_TIMEOUT) / 1000;
    103         } catch (SettingNotFoundException e) {
    104             return 0;
    105         }
    106     }
    107 
    108     @Rpc(description = "Checks the ringer silent mode setting.",
    109             returns = "True if ringer silent mode is enabled.")
    110     public Boolean checkRingerSilentMode() {
    111         return mAudio.getRingerMode() == AudioManager.RINGER_MODE_SILENT;
    112     }
    113 
    114     @Rpc(description = "Toggles ringer silent mode on and off.",
    115             returns = "True if ringer silent mode is enabled.")
    116     public Boolean toggleRingerSilentMode(
    117             @RpcParameter(name = "enabled") @RpcOptional Boolean enabled) {
    118         if (enabled == null) {
    119             enabled = !checkRingerSilentMode();
    120         }
    121         mAudio.setRingerMode(enabled ? AudioManager.RINGER_MODE_SILENT
    122                 : AudioManager.RINGER_MODE_NORMAL);
    123         return enabled;
    124     }
    125 
    126     @Rpc(description = "Set the ringer to a specified mode")
    127     public void setRingerMode(@RpcParameter(name = "mode") Integer mode) throws Exception {
    128         if (AudioManager.isValidRingerMode(mode)) {
    129             mAudio.setRingerMode(mode);
    130         } else {
    131             throw new Exception("Ringer mode " + mode + " does not exist.");
    132         }
    133     }
    134 
    135     @Rpc(description = "Returns the current ringtone mode.",
    136             returns = "An integer representing the current ringer mode")
    137     public Integer getRingerMode() {
    138         return mAudio.getRingerMode();
    139     }
    140 
    141     @Rpc(description = "Returns the maximum ringer volume.")
    142     public int getMaxRingerVolume() {
    143         return mAudio.getStreamMaxVolume(AudioManager.STREAM_RING);
    144     }
    145 
    146     @Rpc(description = "Returns the current ringer volume.")
    147     public int getRingerVolume() {
    148         return mAudio.getStreamVolume(AudioManager.STREAM_RING);
    149     }
    150 
    151     @Rpc(description = "Sets the ringer volume.")
    152     public void setRingerVolume(@RpcParameter(name = "volume") Integer volume) {
    153         mAudio.setStreamVolume(AudioManager.STREAM_RING, volume, 0);
    154     }
    155 
    156     @Rpc(description = "Returns the maximum media volume.")
    157     public int getMaxMediaVolume() {
    158         return mAudio.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
    159     }
    160 
    161     @Rpc(description = "Returns the current media volume.")
    162     public int getMediaVolume() {
    163         return mAudio.getStreamVolume(AudioManager.STREAM_MUSIC);
    164     }
    165 
    166     @Rpc(description = "Sets the media volume.")
    167     public void setMediaVolume(@RpcParameter(name = "volume") Integer volume) {
    168         mAudio.setStreamVolume(AudioManager.STREAM_MUSIC, volume, 0);
    169     }
    170 
    171     /**
    172     * Sets the voice call volume.
    173     * @param volume the volume number to be set for voice call.
    174     */
    175     @Rpc(description = "Sets the voice call volume.")
    176     public void setVoiceCallVolume(@RpcParameter(name = "volume") Integer volume) {
    177         mAudio.setStreamVolume(AudioManager.STREAM_VOICE_CALL, volume, 0);
    178     }
    179 
    180     /**
    181     * Sets the alarm volume.
    182     * @param volume the volume number to be set for alarm.
    183     */
    184     @Rpc(description = "Sets the alarm volume.")
    185     public void setAlarmVolume(@RpcParameter(name = "volume") Integer volume) {
    186         mAudio.setStreamVolume(AudioManager.STREAM_ALARM, volume, 0);
    187     }
    188 
    189     @Rpc(description = "Returns the screen backlight brightness.",
    190             returns = "the current screen brightness between 0 and 255")
    191     public Integer getScreenBrightness() {
    192         try {
    193             return android.provider.Settings.System.getInt(mService.getContentResolver(),
    194                     android.provider.Settings.System.SCREEN_BRIGHTNESS);
    195         } catch (SettingNotFoundException e) {
    196             return 0;
    197         }
    198     }
    199 
    200     @Rpc(description = "return the system time since boot in nanoseconds")
    201     public long getSystemElapsedRealtimeNanos() {
    202         return SystemClock.elapsedRealtimeNanos();
    203     }
    204 
    205     @Rpc(description = "Sets the the screen backlight brightness.",
    206             returns = "the original screen brightness.")
    207     public Integer setScreenBrightness(
    208             @RpcParameter(name = "value", description = "brightness value between 0 and 255") Integer value) {
    209         if (value < 0) {
    210             value = 0;
    211         } else if (value > 255) {
    212             value = 255;
    213         }
    214         final int brightness = value;
    215         Integer oldValue = getScreenBrightness();
    216         android.provider.Settings.System.putInt(mService.getContentResolver(),
    217                 android.provider.Settings.System.SCREEN_BRIGHTNESS, brightness);
    218 
    219         FutureActivityTask<Object> task = new FutureActivityTask<Object>() {
    220             @Override
    221             public void onCreate() {
    222                 super.onCreate();
    223                 WindowManager.LayoutParams lp = getActivity().getWindow().getAttributes();
    224                 lp.screenBrightness = brightness * 1.0f / 255;
    225                 getActivity().getWindow().setAttributes(lp);
    226                 setResult(null);
    227                 finish();
    228             }
    229         };
    230 
    231         FutureActivityTaskExecutor taskExecutor =
    232                 ((BaseApplication) mService.getApplication()).getTaskExecutor();
    233         taskExecutor.execute(task);
    234 
    235         return oldValue;
    236     }
    237 
    238     @Rpc(description = "Returns true if the device is in an interactive state.")
    239     public Boolean isDeviceInteractive() throws Exception {
    240         return mPower.isInteractive();
    241     }
    242 
    243     @Rpc(description = "Issues a request to put the device to sleep after a delay.")
    244     public void goToSleep(Integer delay) {
    245         mPower.goToSleep(SystemClock.uptimeMillis() + delay);
    246     }
    247 
    248     @Rpc(description = "Issues a request to put the device to sleep right away.")
    249     public void goToSleepNow() {
    250         mPower.goToSleep(SystemClock.uptimeMillis());
    251     }
    252 
    253     @Rpc(description = "Issues a request to wake the device up right away.")
    254     public void wakeUpNow() {
    255         mPower.wakeUp(SystemClock.uptimeMillis());
    256     }
    257 
    258     @Rpc(description = "Get Up time of device.",
    259             returns = "Long value of device up time in milliseconds.")
    260     public long getDeviceUpTime() throws Exception {
    261         return SystemClock.elapsedRealtime();
    262     }
    263 
    264     @Rpc(description = "Set a string password to the device.")
    265     public void setDevicePassword(@RpcParameter(name = "password") String password,
    266                                   @RpcParameter(name = "previousPassword")
    267                                   @RpcDefault("")
    268                                   @RpcOptional
    269                                   String previousPassword) {
    270         // mLockPatternUtils.setLockPatternEnabled(true, UserHandle.myUserId());
    271         mLockPatternUtils.setLockScreenDisabled(false, UserHandle.myUserId());
    272         mLockPatternUtils.setCredentialRequiredToDecrypt(true);
    273         mLockPatternUtils.saveLockPassword(password, previousPassword,
    274                 DevicePolicyManager.PASSWORD_QUALITY_NUMERIC, UserHandle.myUserId());
    275     }
    276 
    277     @Rpc(description = "Disable screen lock password on the device. Note that disabling the " +
    278             "screen lock while the screen is locked will still require the screen to be " +
    279             "unlocked via pressing the back button and swiping up. To get around this, make sure " +
    280             "the screen is on/unlocked when calling this method.")
    281     public void disableDevicePassword(
    282             @RpcParameter(name = "currentPassword",
    283                           description = "The current password used to lock the device")
    284             @RpcDefault("1111")
    285             @RpcOptional String currentPassword) {
    286         mLockPatternUtils.clearLock(currentPassword, UserHandle.myUserId());
    287         mLockPatternUtils.setLockScreenDisabled(true, UserHandle.myUserId());
    288     }
    289 
    290     @Rpc(description = "Set the system time in epoch.")
    291     public void setTime(Long currentTime) {
    292         mAlarm.setTime(currentTime);
    293     }
    294 
    295     @Rpc(description = "Set the system time zone.")
    296     public void setTimeZone(@RpcParameter(name = "timeZone") String timeZone) {
    297         mAlarm.setTimeZone(timeZone);
    298     }
    299 
    300     @Rpc(description = "Show Home Screen")
    301     public void showHomeScreen() {
    302         Intent intent = new Intent(Intent.ACTION_MAIN);
    303         intent.addCategory(Intent.CATEGORY_HOME);
    304         intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    305         try {
    306             mAndroidFacade.startActivityIntent(intent, false);
    307         } catch (RuntimeException e) {
    308             Log.d("showHomeScreen RuntimeException" + e);
    309         } catch (Exception e){
    310             Log.d("showHomeScreen exception" + e);
    311         }
    312     }
    313 
    314     @Rpc(description = "Set private DNS mode")
    315     public void setPrivateDnsMode(@RpcParameter(name = "useTls") Boolean useTls,
    316             @RpcParameter(name = "hostname") @RpcOptional String hostname) {
    317         String dnsMode = ConnectivityConstants.PrivateDnsModeOpportunistic;
    318         if(useTls == false) dnsMode = ConnectivityConstants.PrivateDnsModeOff;
    319         if(hostname != null) dnsMode = ConnectivityConstants.PrivateDnsModeStrict;
    320         android.provider.Settings.Global.putString(mService.getContentResolver(),
    321                 android.provider.Settings.Global.PRIVATE_DNS_MODE, dnsMode);
    322         if(hostname != null)
    323             android.provider.Settings.Global.putString(mService.getContentResolver(),
    324                     android.provider.Settings.Global.PRIVATE_DNS_SPECIFIER, hostname);
    325     }
    326 
    327     @Rpc(description = "Get private DNS mode", returns = "Private DNS mode setting")
    328     public String getPrivateDnsMode() {
    329         return android.provider.Settings.Global.getString(mService.getContentResolver(),
    330                 android.provider.Settings.Global.PRIVATE_DNS_MODE);
    331     }
    332 
    333     @Rpc(description = "Get private DNS specifier", returns = "DNS hostname set in strict mode")
    334     public String getPrivateDnsSpecifier() {
    335         if(!getPrivateDnsMode().equals(ConnectivityConstants.PrivateDnsModeStrict)) return null;
    336         return android.provider.Settings.Global.getString(mService.getContentResolver(),
    337                 android.provider.Settings.Global.PRIVATE_DNS_SPECIFIER);
    338     }
    339 
    340     /**
    341      * Enable or disable mobile data.
    342      * @param enabled Enable data: True: Disable data: False.
    343      */
    344     @Rpc(description = "Set Mobile Data Enabled.")
    345     public void setMobileDataEnabled(@RpcParameter(name = "enabled")
    346             @RpcOptional @RpcDefault(value = "true") Boolean enabled) {
    347         mDataController.setMobileDataEnabled(enabled);
    348     }
    349 
    350     /**
    351      * Get mobile data usage info for subscription.
    352      * @return DataUsageInfo: The Mobile data usage information.
    353      */
    354     @Rpc(description = "Get mobile data usage info", returns = "Mobile Data DataUsageInfo")
    355     public DataUsageController.DataUsageInfo getMobileDataUsageInfo(
    356             @RpcOptional @RpcParameter(name = "subId") Integer subId) {
    357         if (subId == null) {
    358             subId = SubscriptionManager.getDefaultDataSubscriptionId();
    359         }
    360         String subscriberId = mTelephonyManager.getSubscriberId(subId);
    361         return mDataController.getMobileDataUsageInfoForSubscriber(subscriberId);
    362     }
    363 
    364     /**
    365      * Get mobile data usage info for for uid.
    366      * @return DataUsageInfo: The Mobile data usage information.
    367      */
    368     @Rpc(description = "Get mobile data usage info", returns = "Mobile Data DataUsageInfo")
    369     public DataUsageController.DataUsageInfo getMobileDataUsageInfoForUid(
    370             @RpcParameter(name = "uId") Integer uId,
    371             @RpcOptional @RpcParameter(name = "subId") Integer subId) {
    372         if (subId == null) {
    373             subId = SubscriptionManager.getDefaultDataSubscriptionId();
    374         }
    375         String subscriberId = mTelephonyManager.getSubscriberId(subId);
    376         return mDataController.getMobileDataUsageInfoForUid(uId, subscriberId);
    377     }
    378 
    379     /**
    380      * Get Wifi data usage info.
    381      * @return DataUsageInfo: The Wifi data usage information.
    382      */
    383     @Rpc(description = "Get wifi data usage info", returns = "Wifi Data DataUsageInfo")
    384     public DataUsageController.DataUsageInfo getWifiDataUsageInfo() {
    385         return mDataController.getWifiDataUsageInfo();
    386     }
    387 
    388     @Override
    389     public void shutdown() {
    390         // Nothing to do yet.
    391     }
    392 }
    393