Merge "FP2-1665: Lock Screen Clock can show negative duration" into fp2-dev-v2
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index d787fdf..d452539 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -2412,6 +2412,7 @@
             IPrivacyImpactService pis = IPrivacyImpactService.Stub.asInterface(ServiceManager.getService("PrivacyImpact"));
             if( intent != null &&
                 intent.getComponent() != null &&
+                pis.isPrivacyImpactEnabled() &&
                 pis.showPackagePrivacy(intent.getComponent().getPackageName())) {
                     Log.i(TAG_TIMELINE, "Timeline: Activity_first_launch "+
                         intent.getComponent().getPackageName() + " time:"
diff --git a/core/java/android/os/IPrivacyImpactService.aidl b/core/java/android/os/IPrivacyImpactService.aidl
index de63781..8768b6a 100644
--- a/core/java/android/os/IPrivacyImpactService.aidl
+++ b/core/java/android/os/IPrivacyImpactService.aidl
@@ -6,4 +6,7 @@
 interface IPrivacyImpactService {
     boolean showPackagePrivacy(String packageName);
     void disablePackagePrivacy(String packageName);
+    void clearPackagePrivacyData();
+    boolean isPrivacyImpactEnabled();
+    void setPrivacyImpactStatus(boolean enabled);
 }
diff --git a/packages/FairphonePrivacyImpact/src/com/fairphone/privacyimpact/GrantAccessActivity.java b/packages/FairphonePrivacyImpact/src/com/fairphone/privacyimpact/GrantAccessActivity.java
index 4bf9e7d..60f5a7c 100644
--- a/packages/FairphonePrivacyImpact/src/com/fairphone/privacyimpact/GrantAccessActivity.java
+++ b/packages/FairphonePrivacyImpact/src/com/fairphone/privacyimpact/GrantAccessActivity.java
@@ -33,6 +33,7 @@
 
     private final static String TAG = GrantAccessActivity.class.getSimpleName();
     private static final String PREFS_PRIVACY_IMPACT = "com.fairphone.privacyimpact.PREFS_PRIVACY_IMPACT";
+    private static final String FIRST_RUN = "com.fairphone.privacyimpact.FIRST_RUN";
     private static final String SHOW_PRIVACY_IMPACT_OOBE = "com.fairphone.privacyimpact.SHOW_PRIVACY_OOBE";
     private static final boolean DEBUG = false;
     
@@ -41,12 +42,11 @@
     @Override
     protected void onCreate(Bundle savedInstance) {
         super.onCreate(savedInstance);
-        Log.wtf(TAG, "GrantAccessActivity - onCreate");
+        Log.i(TAG, "GrantAccessActivity - onCreate");
         try {
             Intent startIntent = getIntent();
-            
+            clearOnFirstRun();
             if (showPrivacyImpact(startIntent)) {
-                 Log.wtf(TAG, "if");
                 try {
                     // setup the layout
                     setupLayout(startIntent);
@@ -55,7 +55,6 @@
                     startApplication(startIntent);
                 }
             } else {
-                Log.wtf(TAG, "else");
                 startApplication(startIntent);
             }
 
@@ -63,6 +62,19 @@
             Log.e(TAG, "Failed to launch Privacy Impact", e);
         }
     }
+    
+    private void clearOnFirstRun(){
+        // Privacy Impact database is kept as a system service, not as part of this app
+        // so we need to explicitly reset it if this app is running for the first time,
+        // in case its data was cleared.
+        SharedPreferences sharedPrefs = getSharedPreferences(PREFS_PRIVACY_IMPACT, Context.MODE_PRIVATE);
+        if (sharedPrefs.getBoolean(FIRST_RUN, true)) {
+            AppSettingsDatabaseHelper.resetPrivacyDatabase();
+            SharedPreferences.Editor editor = sharedPrefs.edit();
+            editor.putBoolean(FIRST_RUN, false);
+            editor.apply();
+        }
+    }
 
     private boolean showPrivacyImpact(final Intent startIntent) {
         Log.wtf(TAG, "GrantAccessActivity - start showPrivacyImpact");
@@ -91,6 +103,11 @@
         // Is the hide popup preference checked?
         SharedPreferences defaultSharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
         boolean popupDisabled = defaultSharedPreferences.getBoolean(HIDE_PRIVACY_IMPACT_PREFERENCE, false);
+        // Validate it matched the system behaviour
+        if( popupDisabled != AppSettingsDatabaseHelper.isPrivacyImpactEnabled()) {
+            Log.e(TAG, "Value mismatch on Privacy Impact enabled status between settings preference and system service");
+            //TODO
+        }
 
         // Has it been validated already?
         boolean impactAccepted =
@@ -243,6 +260,7 @@
                 SharedPreferences.Editor editor = defaultSharedPreferences.edit();
                 editor.putBoolean(HIDE_PRIVACY_IMPACT_PREFERENCE, isChecked);
                 editor.apply();
+                AppSettingsDatabaseHelper.setPrivacyImpactStatus(!isChecked);
             }
         }.setup(this));
     }
diff --git a/packages/FairphonePrivacyImpact/src/com/fairphone/privacyimpact/PrivacyImpactPreferenceActivity.java b/packages/FairphonePrivacyImpact/src/com/fairphone/privacyimpact/PrivacyImpactPreferenceActivity.java
index acce3d5..8bc76a6 100644
--- a/packages/FairphonePrivacyImpact/src/com/fairphone/privacyimpact/PrivacyImpactPreferenceActivity.java
+++ b/packages/FairphonePrivacyImpact/src/com/fairphone/privacyimpact/PrivacyImpactPreferenceActivity.java
@@ -1,9 +1,12 @@
 package com.fairphone.privacyimpact;
 
 import android.os.Bundle;
+import android.preference.Preference;
 import android.preference.PreferenceActivity;
 import android.preference.PreferenceFragment;
 
+import com.fairphone.privacyimpact.database.AppSettingsDatabaseHelper;
+
 /**
  * Created by jpascoal on 13/07/2015.
  */
@@ -11,6 +14,11 @@
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
+    }
+    
+    @Override
+    protected void onResume() {
+        super.onResume();
         getFragmentManager().beginTransaction().replace(android.R.id.content, new MyPreferenceFragment()).commit();
     }
 
@@ -19,6 +27,17 @@
         public void onCreate(final Bundle savedInstanceState) {
             super.onCreate(savedInstanceState);
             addPreferencesFromResource(R.xml.privacy_impact_preference);
+            Preference p = findPreference(GrantAccessActivity.HIDE_PRIVACY_IMPACT_PREFERENCE);
+            p.setOnPreferenceChangeListener(
+                new Preference.OnPreferenceChangeListener() {
+                    @Override
+                    public boolean onPreferenceChange (Preference preference, Object newValue) {
+                        final boolean val = (Boolean) newValue;
+                        AppSettingsDatabaseHelper.setPrivacyImpactStatus(!val);
+                        return true;
+                    }
+                }
+            );
         }
     }
 }
diff --git a/packages/FairphonePrivacyImpact/src/com/fairphone/privacyimpact/database/AppSettingsDatabaseHelper.java b/packages/FairphonePrivacyImpact/src/com/fairphone/privacyimpact/database/AppSettingsDatabaseHelper.java
index 1b05b8f..19cef1d 100644
--- a/packages/FairphonePrivacyImpact/src/com/fairphone/privacyimpact/database/AppSettingsDatabaseHelper.java
+++ b/packages/FairphonePrivacyImpact/src/com/fairphone/privacyimpact/database/AppSettingsDatabaseHelper.java
@@ -29,5 +29,34 @@
             Log.e(TAG, "Failed to set package "+packageName+" from service", e);
         }
     }
+    
+    public static void resetPrivacyDatabase(){
+        try {
+            IPrivacyImpactService pis = IPrivacyImpactService.Stub.asInterface(ServiceManager.getService("PrivacyImpact"));
+            pis.clearPackagePrivacyData();
+        } catch (Exception e) {
+            Log.e(TAG, "Failed to clear privacy impact database", e);
+        }
+    }
+    
+    public static boolean isPrivacyImpactEnabled(){
+        boolean result = false;
+        try {
+            IPrivacyImpactService pis = IPrivacyImpactService.Stub.asInterface(ServiceManager.getService("PrivacyImpact"));
+            result = !pis.isPrivacyImpactEnabled();
+        } catch (Exception e) {
+            Log.e(TAG, "Failed to get privacy impact enable status. Fallback to disabled.", e);
+        }
+        return result;
+    }
+    
+    public static void setPrivacyImpactStatus(boolean enabled){
+        try {
+            IPrivacyImpactService pis = IPrivacyImpactService.Stub.asInterface(ServiceManager.getService("PrivacyImpact"));
+            pis.setPrivacyImpactStatus(enabled);
+        } catch (Exception e) {
+            Log.e(TAG, "Failed to get privacy impact enable status. Fallback to disabled.", e);
+        }
+    }
 }
 
diff --git a/services/core/java/com/android/server/am/PrivacyImpactService.java b/services/core/java/com/android/server/am/PrivacyImpactService.java
index d7603a0..62add20 100644
--- a/services/core/java/com/android/server/am/PrivacyImpactService.java
+++ b/services/core/java/com/android/server/am/PrivacyImpactService.java
@@ -5,6 +5,7 @@
 
 import android.content.ContentValues;
 import android.content.Context;
+import android.content.SharedPreferences;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
 import android.database.Cursor;
@@ -16,6 +17,9 @@
 public class PrivacyImpactService extends IPrivacyImpactService.Stub {
     private static final String TAG = "PrivacyImpactService";
 
+    public static final String PREFS_NAME           = "privacy_prefs";
+    public static final String PREFS_ENABLED           = "privacy_prefs";
+    
     public static final String TABLE_NAME           = "popup";
     public static final String COLUMN_ID            = "_id";
     public static final String COLUMN_PACKAGE_NAME  = "name";
@@ -238,11 +242,12 @@
         }
     );
     private final SQLiteOpenHelper mHelper;
+    private final SharedPreferences mPrefs;
 
     public PrivacyImpactService(Context context) {
         super();
         mContext = context;
-        Log.wtf(TAG, "Starting PrivacyImpactService");
+        Log.i(TAG, "Starting PrivacyImpactService");
         
         mHelper = new SQLiteOpenHelper(context, DB_NAME, null, DB_VERSION) {
             @Override
@@ -261,15 +266,16 @@
                 onCreate(db);
             }
         };
-        Log.wtf(TAG, "Started PrivacyImpactService");
+        mPrefs = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
+        Log.d(TAG, "Started PrivacyImpactService");
     }
 
 
     public boolean showPackagePrivacy(String packageName) {
-        Log.wtf(TAG, "Querying Package name: " + packageName);
+        Log.i(TAG, "Querying Package name: " + packageName);
         boolean show = false;
 
-        Log.wtf(TAG, "checking if it is in whitelist "+sWhitelist.contains(packageName));
+        Log.i(TAG, "checking if it is in whitelist "+sWhitelist.contains(packageName));
         // Don't show Privacy Impact for whitelisted apps
         if (!sWhitelist.contains(packageName)) {
             // Don't show Privacy Impact for system apps
@@ -301,7 +307,7 @@
     }
 
     public void disablePackagePrivacy(String packageName) {
-        Log.wtf(TAG, "Adding Package name: " + packageName);
+        Log.i(TAG, "Adding Package name: " + packageName);
         SQLiteDatabase db = mHelper.getWritableDatabase();
 
         // Create a new map of values, where column names are the keys
@@ -310,4 +316,26 @@
 
         db.insert(TABLE_NAME, null, values);
     }
+    
+    public void clearPackagePrivacyData() {
+        Log.i(TAG, "Clearing Privacy Impact database");
+        SQLiteDatabase db = mHelper.getWritableDatabase();
+        db.delete(TABLE_NAME, null, null);
+        SharedPreferences.Editor editor = mPrefs.edit();
+        editor.remove(PREFS_ENABLED);
+        editor.apply();
+    }
+    
+    public boolean isPrivacyImpactEnabled() {
+        boolean result = mPrefs.getBoolean(PREFS_ENABLED, true);
+        Log.i(TAG, "isPrivacyImpactEnabled() = "+result);
+        return result;
+    }
+    
+    public void setPrivacyImpactStatus(boolean enabled) {
+        SharedPreferences.Editor editor = mPrefs.edit();
+        editor.putBoolean(PREFS_ENABLED, enabled);
+        editor.apply();
+        Log.i(TAG, "setPrivacyImpactStatus("+enabled+")");
+    }
 }