android4.2 recovery&reset_factory

settings中,恢复出场设置

 

1:frameworks/base/core/java/android/os/RecoverySystem.java

 

public static voidrebootWipeUserData(Context context) throws IOException {

 

       final ConditionVariable condition = new ConditionVariable();

 

 

 

       Intent intent = newIntent("android.intent.action.MASTER_CLEAR_NOTIFICATION");

 

       context.sendOrderedBroadcastAsUser(intent, UserHandle.OWNER,

 

                android.Manifest.permission.MASTER_CLEAR,

 

                new BroadcastReceiver() {

 

                    @Override

 

                    public voidonReceive(Context context, Intent intent) {

 

                        condition.open();

 

                    }

 

                }, null, 0, null, null);

 

 

 

       // Block until the ordered broadcast has completed.

 

       condition.block();

 

 

 

       Log.d(TAG,"++++sam debug settints backup&reset 111111  data--------- ");

 

       bootCommand(context,"--wipe_data\n--locale=" + Locale.getDefault().toString());

 

   }

 

 

 

 

frameworks/base/services/java/com/android/server/MasterClearReceiver.java

public class MasterClearReceiverextends BroadcastReceiver {

 

   private static final String TAG = "MasterClear";

 

 

 

   @Override

 

   public void onReceive(final Context context, final Intent intent) {

 

       if (intent.getAction().equals(Intent.ACTION_REMOTE_INTENT)) {

 

            if(!"google.com".equals(intent.getStringExtra("from"))) {

 

                Slog.w(TAG, "Ignoringmaster clear request -- not from trusted server.");

 

                return;

 

            }

 

       }

 

 

 

       Slog.w(TAG, "!!! FACTORY RESET!!!");

 

       // The reboot call is blocking, so we need to do it on another thread.

 

       Thread thr = new Thread("Reboot") {

 

            @Override

 

            public void run() {

 

                try {

 

                    RecoverySystem.rebootWipeUserData(context);

 

                    Log.wtf(TAG, "Stillrunning after master clear?!");

 

                } catch (IOException e) {

 

                    Slog.e(TAG, "Can'tperform master clear/factory reset", e);

 

                }

 

            }

 

       };

 

       thr.start();

 

   }

 

}

 

~                              

 

 

 

 

 

////

 

 

 

2: private static void bootCommand(Context context, String arg) throwsIOException {

 

       RECOVERY_DIR.mkdirs();  // In casewe need it

 

       COMMAND_FILE.delete();  // In caseit's not writable

 

       LOG_FILE.delete();

 

 

 

       FileWriter command = new FileWriter(COMMAND_FILE);

 

       try {

 

            command.write(arg);

 

            command.write("\n");

 

       } finally {

 

            command.close();

 

       }

 

 

 

       Log.d(TAG,"++++sam debug settints backup&reset erasedata--------------------- ");

 

 

 

 

 

       // Having written the command file, go ahead and reboot

 

       PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);

 

       pm.reboot("recovery");

 

 

 

       throw new IOException("Reboot failed (no permissions?)");

 

   }

 

 

 

////  /frameworks/base/core/java/android/os/PowerManager.java

 

 

 

 

 

 /**

 

    * Reboot the device.  Will notreturn if the reboot is successful.

 

    * <p>

 

    * Requires the {@link android.Manifest.permission#REBOOT} permission.

 

    * </p>

 

    *

 

    * @param reason code to pass to the kernel (e.g., "recovery")to

 

    *               request specialboot modes, or null.

 

    */

 

   public void reboot(String reason) {

 

       try {

 

            mService.reboot(false,reason, true);

 

       } catch (RemoteException e) {

 

       }

 

   }

 

 

 

////

 

3:mService.reboot-----/base/core/java/android/os/IPowerManager.aidl()////

 

                 -----base/services/java/com/android/server/power/PowerManagerService.java

 

 

 

 /**

 

    * Reboots the device.

 

    *

 

    * @param confirm If true, shows a reboot confirmation dialog.

 

    * @param reason The reason for the reboot, or null if none.

 

    * @param wait If true, this call waits for the reboot to complete anddoes not return.

 

    */

 

   @Override // Binder call

 

   public void reboot(boolean confirm, String reason, boolean wait) {

 

       mContext.enforceCallingOrSelfPermission(android.Manifest.permission.REBOOT,null);

 

 

 

       final long ident = Binder.clearCallingIdentity();

 

       try {

 

            shutdownOrRebootInternal(false, confirm,reason, wait);

 

       } finally {

 

            Binder.restoreCallingIdentity(ident);

 

       }

 

   }

 

 

 

 private void shutdownOrRebootInternal(final boolean shutdown, finalboolean confirm,

 

            final String reason, boolean wait){

 

       if (mHandler == null || !mSystemReady) {

 

            throw newIllegalStateException("Too early to call shutdown() or reboot()");

 

       }

 

 

 

       Runnable runnable = new Runnable() {

 

           @Override

 

            public void run() {

 

                synchronized (this) {

 

                    if (shutdown) {

 

                        ShutdownThread.shutdown(mContext, confirm);

 

                    } else {

 

                        ShutdownThread.reboot(mContext,reason, confirm);

 

                    }

 

                }

 

            }

 

       };

 

                  

 

4:./base/services/java/com/android/server/power/ShutdownThread.java

 

   /**

 

    * Request a clean shutdown, waiting for subsystems to clean up their

 

    * state etc.  Must be called froma Looper thread in which its UI

 

    * is shown.

 

    *

 

    * @param context Context used to display the shutdown progress dialog.

 

    * @param reason code to pass to the kernel (e.g. "recovery"),or null.

 

    * @param confirm true if user confirmation is needed before shuttingdown.

 

    */

 

   public static void reboot(final Context context, String reason, booleanconfirm) {

 

       mReboot = true;

 

       mRebootSafeMode = false;

 

       mRebootReason = reason;

 

       shutdownInner(context,confirm);

 

   }

 

 

 

5: 由shutdownInner------

 

static void shutdownInner(finalContext context, boolean confirm) {

 

       // ensure that only one thread is trying to power down.

 

       // any additional calls arejust returned

 

       synchronized (sIsStartedGuard) {

 

            if (sIsStarted) {

 

                Log.d(TAG, "Request toshutdown already running, returning.");

 

                return;

 

            }

 

       }

 

 

 

       final int longPressBehavior =context.getResources().getInteger(

 

                        com.android.internal.R.integer.config_longPressOnPowerBehavior);

 

       final int resourceId = mRebootSafeMode

 

                ?com.android.internal.R.string.reboot_safemode_confirm

 

                : (longPressBehavior == 2

 

                        ?com.android.internal.R.string.shutdown_confirm_question

 

                        :com.android.internal.R.string.shutdown_confirm);

 

 

 

       Log.d(TAG, "Notifying thread to start shutdownlongPressBehavior=" + longPressBehavior);

 

 

 

       if (confirm) {

 

            final CloseDialogReceiver closer =new CloseDialogReceiver(context);

 

            if (sConfirmDialog != null) {

 

                sConfirmDialog.dismiss();

 

            }

 

            sConfirmDialog = newAlertDialog.Builder(context)

 

                    .setTitle(mRebootSafeMode

 

                            ?com.android.internal.R.string.reboot_safemode_title

 

                            : com.android.internal.R.string.power_off)

 

                    .setMessage(resourceId)

 

                    .setPositiveButton(com.android.internal.R.string.yes,new DialogInterface.OnClickListener() {

 

                        public voidonClick(DialogInterface dialog, int which) {

 

                               Log.d(TAG,"++++SAMDEBUG BBBBBBBBBBBBBBBBBBBB");

 

              beginShutdownSequence(context);

 

                        }

 

                    })

 

                    .setNegativeButton(com.android.internal.R.string.no,null)

 

                    .create();

 

            closer.dialog = sConfirmDialog;

 

            sConfirmDialog.setOnDismissListener(closer);

 

            sConfirmDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);

 

            sConfirmDialog.show();

 

       } else {

 

        Log.d(TAG,"++++SAM DEBUGccccccccccccccccccccccccccccccccccccccccc");

 

            beginShutdownSequence(context);

 

       }

 

   }

 

 

 

 

 

 

 

6: private static voidbeginShutdownSequence(Context context) {

 

       synchronized(sIsStartedGuard) {

 

            if (sIsStarted) {

 

                Log.d(TAG, "Shutdownsequence already running, returning.");

 

                return;

 

            }

 

            sIsStarted = true;

 

       }

 

 

 

       // throw up an indeterminate system dialog to indicate radio is

 

       // shutting down.

 

       ProgressDialog pd = new ProgressDialog(context);

 

       pd.setTitle(context.getText(com.android.internal.R.string.power_off));

 

       pd.setMessage(context.getText(com.android.internal.R.string.shutdown_progress));

 

       pd.setIndeterminate(true);

 

       pd.setCancelable(false);

 

       pd.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);

 

 

 

       pd.show();

 

 

 

       sInstance.mContext = context;

 

       sInstance.mPowerManager =(PowerManager)context.getSystemService(Context.POWER_SERVICE);

 

 

 

       // make sure we never fall asleep again

 

       sInstance.mCpuWakeLock = null;

 

       try {

 

            sInstance.mCpuWakeLock = sInstance.mPowerManager.newWakeLock(

 

                    PowerManager.PARTIAL_WAKE_LOCK,TAG + "-cpu");

 

            sInstance.mCpuWakeLock.setReferenceCounted(false);

 

            sInstance.mCpuWakeLock.acquire();

 

       } catch (SecurityException e) {

 

           Log.w(TAG, "Nopermission to acquire wake lock", e);

 

            sInstance.mCpuWakeLock = null;

 

       }

 

 

 

       // also make sure the screen stays on for better user experience

 

       sInstance.mScreenWakeLock = null;

 

       if (sInstance.mPowerManager.isScreenOn()) {

 

            try {

 

                sInstance.mScreenWakeLock =sInstance.mPowerManager.newWakeLock(

 

                        PowerManager.FULL_WAKE_LOCK,TAG + "-screen");

 

                sInstance.mScreenWakeLock.setReferenceCounted(false);

 

                sInstance.mScreenWakeLock.acquire();

 

            } catch (SecurityException e) {

 

                Log.w(TAG, "No permissionto acquire wake lock", e);

 

                sInstance.mScreenWakeLock =null;

 

            }

 

        }

 

 

 

       // start the thread that initiates shutdown

 

       sInstance.mHandler = new Handler() {

 

       };

 

    Log.d(TAG,"++++SAMDEBUG AAAAAAAAAAAAAAAAAAAAAAAAAAA");

 

       sInstance.start();

 

   }

 

 

 

   void actionDone() {

 

       synchronized (mActionDoneSync) {

 

            mActionDone = true;

 

            mActionDoneSync.notifyAll();

 

       }

 

   }

 

 

 

   /**

 

    * Makes sure we handle the shutdown gracefully.

 

    * Shuts off power regardless of radio and bluetooth state if the allotedtime has passed.

 

    */

 

   public void run() {

 

       BroadcastReceiver br = new BroadcastReceiver() {

 

            @Override public voidonReceive(Context context, Intent intent) {

 

                // We don't allow apps tocancel this, so ignore the result.

 

                actionDone();

 

            }

 

       };

 

 

 

    Log.d(TAG,"++++samdebug run 11111111111111111111111-----");

 

 

 

       /*

 

         * Write a system property in case thesystem_server reboots before we

 

         * get to the actual hardware restart.If that happens, we'll retry at

 

         * the beginning of the SystemServerstartup.

 

         */

 

       {

 

            String reason = (mReboot ?"1" : "0") + (mRebootReason != null ? mRebootReason :"");

 

            SystemProperties.set(SHUTDOWN_ACTION_PROPERTY,reason);

 

       }

 

 

 

       /*

 

         * If we are rebooting into safe mode,write a system property

 

         * indicating so.

 

         */

 

       if (mRebootSafeMode) {

 

            SystemProperties.set(REBOOT_SAFEMODE_PROPERTY,"1");

 

       }

 

 

 

       Log.i(TAG, "Sending shutdown broadcast...");

 

       

 

       // First send the high-level shut down broadcast.

 

       mActionDone = false;

 

       mContext.sendOrderedBroadcastAsUser(new Intent(Intent.ACTION_SHUTDOWN),

 

                UserHandle.ALL, null, br,mHandler, 0, null, null);

 

       

 

       final long endTime = SystemClock.elapsedRealtime() + MAX_BROADCAST_TIME;

 

       synchronized (mActionDoneSync) {

 

            while (!mActionDone) {

 

                long delay = endTime -SystemClock.elapsedRealtime();

 

                if (delay <= 0) {

 

                    Log.w(TAG, "Shutdownbroadcast timed out");

 

                    break;

 

                }

 

                try {

 

                    mActionDoneSync.wait(delay);

 

                } catch (InterruptedExceptione) {

 

                }

 

            }

 

       }

 

       

 

       Log.i(TAG, "Shutting down activity manager...");

 

       

 

       final IActivityManager am =

 

           ActivityManagerNative.asInterface(ServiceManager.checkService("activity"));

 

       if (am != null) {

 

            try {

 

                am.shutdown(MAX_BROADCAST_TIME);

 

            } catch (RemoteException e) {

 

            }

 

       }

 

 

 

       // Shutdown radios.

 

       shutdownRadios(MAX_RADIO_WAIT_TIME);

 

 

 

       // Shutdown MountService to ensure media is in a safe state

 

       IMountShutdownObserver observer = new IMountShutdownObserver.Stub() {

 

            public void onShutDownComplete(intstatusCode) throws RemoteException {

 

                Log.w(TAG, "Result code" + statusCode + " from MountService.shutdown");

 

                actionDone();

 

            }

 

       };

 

 

 

       Log.i(TAG, "Shutting down MountService");

 

 

 

       // Set initial variables andtime out time.

 

       mActionDone = false;

 

       final long endShutTime = SystemClock.elapsedRealtime() +MAX_SHUTDOWN_WAIT_TIME;

 

       synchronized (mActionDoneSync) {

 

            try {

 

                final IMountService mount =IMountService.Stub.asInterface(

 

                        ServiceManager.checkService("mount"));

 

                if (mount != null) {

 

                    mount.shutdown(observer);

 

                } else {

 

                    Log.w(TAG,"MountService unavailable for shutdown");

 

                }

 

            } catch (Exception e) {

 

                Log.e(TAG, "Exceptionduring MountService shutdown", e);

 

            }

 

            while (!mActionDone) {

 

                long delay = endShutTime -SystemClock.elapsedRealtime();

 

                if (delay <= 0) {

 

                    Log.w(TAG, "Shutdownwait timed out");

 

                    break;

 

                }

 

                try {

 

                    mActionDoneSync.wait(delay);

 

                } catch (InterruptedExceptione) {

 

                }

 

            }

 

       }

 

 

 

       rebootOrShutdown(mReboot,mRebootReason);

 

   }

 

 

 

 

 

 

 

 

 

5:mRebootReason----

 

rebootOrShutdown(mReboot,mRebootReason);---

 

 

 

   /**

 

    * Do not call this directly. Use {@link #reboot(Context, String,boolean)}

 

    * or {@link #shutdown(Context, boolean)} instead.

 

    *

 

    * @param reboot true to reboot or false to shutdown

 

    * @param reason reason for reboot

 

    */

 

   public static void rebootOrShutdown(boolean reboot, String reason) {

 

       if (reboot) {

 

            Log.i(TAG, "Rebooting, reason:" + reason);

 

            try {

 

                PowerManagerService.lowLevelReboot(reason);

 

            } catch (Exception e) {

 

                Log.e(TAG, "Reboot failed,will attempt shutdown instead", e);

 

            }

 

       } else if (SHUTDOWN_VIBRATE_MS > 0) {

 

            // vibrate before shutting down

 

            Vibrator vibrator = newSystemVibrator();

 

            try {

 

                vibrator.vibrate(SHUTDOWN_VIBRATE_MS);

 

            } catch (Exception e) {

 

                // Failure to vibrate shouldn'tinterrupt shutdown.  Just log it.

 

                Log.w(TAG, "Failed tovibrate during shutdown.", e);

 

           }

 

 

 

            // vibrator is asynchronous so weneed to wait to avoid shutting down too soon.

 

            try {

 

                Thread.sleep(SHUTDOWN_VIBRATE_MS);

 

            } catch (InterruptedExceptionunused) {

 

            }

 

       }

 

 

 

       // Shutdown power

 

       Log.i(TAG, "Performing low-level shutdown...");

 

       PowerManagerService.lowLevelShutdown();

 

   }

 

}

 

 

 

PowerManagerService.lowLevelReboot(reason);

 

 

 

 

 

 PowerManagerService.lowLevelShutdown();

 

 

 

 

 

6:  

 

   /**

 

    * Low-level function turn the device off immediately, without trying

 

    * to be clean.  Most people shoulduse {@link ShutdownThread} for a clean shutdown.

 

    */

 

   public static void lowLevelShutdown() {

 

       nativeShutdown();

 

   }

 

 

 

   /**

 

    * Low-level function to reboot the device.

 

    *

 

    * @param reason code to pass to the kernel (e.g. "recovery"),or null.

 

    * @throws IOException if reboot fails for some reason (eg, lack of

 

    *         permission)

 

    */

 

    publicstatic void lowLevelReboot(String reason) throws IOException {

 

       nativeReboot(reason);

 

   }

 

 

 

7:frameworks/base/services/jni/com_android_server_power_PowerManagerService.cpp

 

static void nativeShutdown(JNIEnv*env, jclass clazz) {

 

   android_reboot(ANDROID_RB_POWEROFF, 0, 0);

 

}

 

 

 

static void nativeReboot(JNIEnv *env,jclass clazz, jstring reason) {

 

   if (reason == NULL) {

 

       android_reboot(ANDROID_RB_RESTART, 0, 0);

 

   } else {

 

       const char *chars = env->GetStringUTFChars(reason, NULL);

 

       android_reboot(ANDROID_RB_RESTART2,0, (char *) chars);

 

       env->ReleaseStringUTFChars(reason, chars);  // In case it fails.

 

   }

 

   jniThrowIOException(env, errno);

 

}

 

 

 

8:system/core/libcutils/android_reboot.c

 

int android_reboot(int cmd, int flags,char *arg)

{

   int ret;

 

 

   if (!(flags & ANDROID_RB_FLAG_NO_SYNC))

       sync();

 

 

   if (!(flags & ANDROID_RB_FLAG_NO_REMOUNT_RO))

       remount_ro();

 

 

   switch (cmd) {

       caseANDROID_RB_RESTART:

            ret = reboot(RB_AUTOBOOT);

            break;

 

 

       case ANDROID_RB_POWEROFF:

            ret = reboot(RB_POWER_OFF);

            break;

 

 

       caseANDROID_RB_RESTART2:

            ret = __reboot(LINUX_REBOOT_MAGIC1,LINUX_REBOOT_MAGIC2,

                           LINUX_REBOOT_CMD_RESTART2,arg);

            break;

 

 

       default:

            ret = -1;

   }

 

 

   return ret;

}

 

 

 

 

 

 

 

 

 

 

 

int format_unknown_device(const char *device, const char* path, const char *fs_type) { 991 LOGW("clean the partition %s in the rm - rf way \n", path); 992 993 static char tmp[PATH_MAX]; 994 bool DEBUG = false; 995 if (strcmp(path, "/data") == 0) { 996 char property_wipemedia[PROPERTY_VALUE_MAX+1]; 997 persist_property_get("persist.sys.wipemedia", property_wipemedia, "0"); 998 printf("In format_unknown_device funtion, persist.sys.wipemedia is %s \n", property_wipemedia); 999 1000 ensure_path_mounted(path); 1001 1002 //Yang.Li@PSW.AD.Recovery.1596362, 2018/11/26, Add for master clear in FBE 1003 /*if (encrypt_type == 1) { 1004 int pw_type = get_password_type(0); 1005 if (pw_type > 0) { 1006 bool reset_pwd_ret = false; 1007 char secret_buffer[65] = {0}; 1008 bool ret = get_secret_hex((uint8_t*)secret_buffer); 1009 secret_buffer[64] = 0; 1010 std::string secret_hex = secret_buffer; 1011 reset_pwd_ret = fscrypt_clear_user_key_auth(0, 0, "!", secret_hex); 1012 printf("fscrypt_clear_user_key_auth, reset_pwd_ret=%d \n", reset_pwd_ret); 1013 reset_pwd_ret = fscrypt_fixate_newest_user_key_auth(0); 1014 printf("fscrypt_fixate_newest_user_key_auth is %d\n", reset_pwd_ret); 1015 } 1016 }*/ 1017 1018 #ifdef OPLUS_FEATURE_RECOVERY_BOOT 1019 //Yang.Li@ANDROID.UPDATABILITY, 2016/09/18, Add for deleting other special data when wipe sdcard 1020 /*if (strcmp(property_wipemedia, "0") != 0) { 1021 //Xuefeng.Peng@PSW.AD.Recovery.1880299, 2019/03/06, Add for deleting user 999 1022 fscrypt_unlock_user_key(999, 10, "!", "!"); 1023 fscrypt_destroy_user_key(999); 1024 fscrypt_destroy_user_storage("", 999, STORAGE_FLAG_DE | STORAGE_FLAG_CE); 1025 sprintf(tmp, "rm -rf /data/misc/vold/user_keys/ce/999"); 1026 __system(tmp); 1027 sprintf(tmp, "rm -rf /data/misc/vold/user_keys/de/999"); 1028 __system(tmp); 1029 //end Xuefeng.Peng modify 1030 LOGW("persist.sys.wipemedia isn't 0, delete /data/media/999.......\n"); 1031 sprintf(tmp, "rm -rf /data/media/999/*"); 1032 __system(tmp); 1033 sprintf(tmp, "rm -rf /data/media/999/.*"); 1034 __system(tmp); 1035 1036 //delete actual data in /sdcard/Android/obb 1037 sprintf(tmp, "rm -rf /data/media/obb/*"); 1038 __system(tmp); 1039 sprintf(tmp, "rm -rf /data/media/obb/.*"); 1040 __system(tmp); 1041 }*/ 1042 #endif /* OPLUS_FEATURE_RECOVERY_BOOT */ 1043 1044 if (strcmp(property_wipemedia, "3") == 0) { 1045 LOGW("persist.sys.wipemedia is 3, only delete /data/media/0.......\n"); 1046 //sprintf(tmp, "cd /data/media/0 ; for f in $(ls -a); do rm -rf $f; done"); 1047 sprintf(tmp, "rm -rf /data/media/0/*"); 1048 __system(tmp); 1049 //#wangzequan@EXP.sysFramework.recovery, 2015/08/24, modify for bug684379:factory mode cannot remove hidden files 1050 sprintf(tmp, "rm -rf /data/media/0/.*"); 1051 __system(tmp); 1052 return 0; 1053 } 1054 1055 if (strcmp(property_wipemedia, "2") == 0) { 1056 static char property_auto_masterclear[PROPERTY_VALUE_MAX+1]; 1057 property_get("persist.sys.auto.masterclear", property_auto_masterclear, ""); 1058 printf("In format_unknown_device funtion, persist.sys.auto.masterclear is %s \n", property_auto_masterclear); 1059 1060 if (strcmp(property_auto_masterclear, "1") == 0) { 1061 printf("In format_unknown_device funtion, echo 1 > %s \n", "/data/engineermode/engineermode_masterclear_flag"); 1062 sprintf(tmp, "echo 1 > %s", "/data/engineermode/engineermode_masterclear_flag"); 1063 __system(tmp); 1064 } 1065 1066 DEBUG = true; 1067 LOGW("before Formatting /data/media/0.......\n"); 1068 //printDir("/data/media/0"); 1069 //ensure_path_mounted("/system"); 1070 format_except_builtin(); 1071 LOGW("after Formatting /data/media/0.......\n"); 1072 //printDir("/data/media/0"); 1073 1074 sprintf(tmp, "toybox find /data/media/0/* | toybox sed 's#/data/media/0/##g' | toybox sort > %s", "/data/engineermode/data_file_after_clear.txt"); 1075 __system(tmp); 1076 } 1077 1078 //ifdef OPLUS_FEATURE_RECOVERY_BOOT 1079 //Yang.Li@ANDROID.UPDATABILITY.1122242, 2018/01/25, Remove for transfer the task of deleting /data/app built-in apks to PMS 1080 /*if (access("/data/app", F_OK) != -1) { 1081 LOGW("rm /data/app exception built-in apk \n"); 1082 sprintf(tmp, "cd /data/app; ls | toybox sort > allfilelist; cat builtinlist | toybox sort > builtinlist_sort; cat builtinlist_sort >> %s; cat allfilelist >> %s; toybox diff -a builtinlist_sort allfilelist >> %s", TEMPORARY_LOG_FILE, TEMPORARY_LOG_FILE, TEMPORARY_LOG_FILE); 1083 __system(tmp); 1084 sprintf(tmp, "cd /data/app; toybox diff -a builtinlist_sort allfilelist | toybox grep ^+ | toybox sed '1d'| toybox sed 's/+//g' | toybox grep -v builtinlist_s | toybox grep -v allfilelist | toybox grep -v packages.xml | while read line; do echo \"$line\" >> %s; rm -rf \"$line\"; done" , TEMPORARY_LOG_FILE); 1085 __system(tmp); 1086 } else { 1087 LOGW("error access /data/app"); 1088 }*/ 1089 //#endif /* OPLUS_FEATURE_RECOVERY_BOOT */ 1090 #ifdef OPLUS_FEATURE_RECOVERY_BOOT 1091 //#wangzequan@EXP.sysFrameworks.recovery, 2016/03/04, modify for avoiding data mount fail, clear system files 1092 if (access("/data/media", F_OK) != -1) { 1093 //Yang.Li@PSW.AD.Recovery.1596362, 2018/12/03, Modify for master clear in FBE or FDE. 1094 if (encrypt_type == 1) { 1095 sprintf(tmp, "cd /data ; for f in $(ls -a | grep -E -v \"^(misc|media|\.layout_version|app|reserve|gr|engineermode|theme_bak|data|opponvitems|etc|format_unclear|dalvik-cache|unencrypted)$\"); do rm -rf $f; done"); 1096 __system(tmp); 1097 1098 //Delete /data/misc except /data/misc/vold/user_keys 1099 sprintf(tmp, "cd /data/misc; ls -a | grep -E -v \"^(vold|gatekeeper)$\" | xargs rm -rf; cd /data/misc/vold; ls -a | grep -v \"^user_keys$\" | xargs rm -rf;"); 1100 __system(tmp); 1101 __system("rm -rf /data/misc/vold/user_keys/test_secret"); 1102 1103 //Delete Multi-User data file 1104 sprintf(tmp, "cd /data ; for f in $(ls -a | grep -E \"^(misc_ce|system_ce|vendor_ce|user|media|misc_de|system_de|user_de|vendor_de)$\"); do cd $f; ls -a | grep -E \"^([1-9][0-9]*){1,3}$\" | xargs rm -rf; cd ../; done"); 1105 __system(tmp); 1106 //Delete /data/misc/vold/user_keys/ce and /data/misc/vold/user_keys/de except 0 1107 sprintf(tmp, "cd /data/misc/vold/user_keys/ce; ls -a | grep -v \"^0$\" | xargs rm -rf; cd /data/misc/vold/user_keys/de; ls -a | grep -v \"^0$\" | xargs rm -rf;"); 1108 __system(tmp); 1109 } else { 1110 sprintf(tmp, "cd /data ; for f in $(ls -a | grep -E -v \"^(media|\.layout_version|app|reserve|gr|engineermode|theme_bak|data|opponvitems|etc|format_unclear|dalvik-cache)$\"); do rm -rf $f; done"); 1111 __system(tmp); 1112 } 1113 1114 #ifdef OPLUS_FEATURE_RECOVERY_BOOT 1115 //#Fangfang.Hui@ANDROID.UPDATABILITY, 2017/02/13, Add for delete /data/data/ directory here, only delete com.coloros.encryption when /data/media/0 is deleted 1116 if (strcmp(property_wipemedia, "3") == 0) { 1117 __system("rm -rf /data/data/com.coloros.encryption"); 1118 } else { 1119 //WangFuJiang@ANDROID.CUSTOMIZE, 2020/05/19, reserve passwordmanager 1120 if (noWipeData()) { 1121 sprintf(tmp, "rm -rf /data/data"); 1122 } else { 1123 sprintf(tmp, "cd /data/data ; for f in $(ls -a | grep -E -v \"(mb.passwordmanager)$\"); do rm -rf $f; done"); 1124 } 1125 __system(tmp); 1126 } 1127 #endif /*OPLUS_FEATURE_RECOVERY_BOOT*/ 1128 } else { 1129 LOGW("error access /data/media"); 1130 } 1131 #endif 1132 1133 if (strcmp(property_wipemedia, "1") == 0) { 1134 LOGW("persist.sys.wipemedia is 1, delete /data/media/0 also .......\n"); 1135 sprintf(tmp, "rm -rf /data/media/0/*"); 1136 __system(tmp); 1137 //#wangzequan@EXP.sysFramework.recovery, 2015/08/24, modify for bug684379:factory mode cannot remove hidden files 1138 sprintf(tmp, "rm -rf /data/media/0/.*"); 1139 __system(tmp); 1140 } 1141 1142 // if the /data/media sdcard has already been migrated for android 4.2, 1143 // prevent the migration from happening again by writing the .layout_version 1144 struct stat st; 1145 if (0 == lstat("/data/media/0", &st)) { 1146 char* layout_version = "2"; 1147 FILE* f = fopen("/data/.layout_version", "wb"); 1148 if (NULL != f) { 1149 fwrite(layout_version, 1, 2, f); 1150 fclose(f); 1151 } else { 1152 LOGW("error opening /data/.layout_version for write.\n"); 1153 } 1154 } else { 1155 LOGW("/data/media/0 not found. migration may occur.\n"); 1156 } 1157 } else { 1158 ensure_path_mounted(path); 1159 LOGW("Formatting data.......\n"); 1160 sprintf(tmp, "rm -rf %s/*", path); 1161 __system(tmp); 1162 sprintf(tmp, "rm -rf %s/.*", path); 1163 __system(tmp); 1164 } 1165 1166 if (DEBUG) { 1167 LOGW("after Formatting data.......\n"); 1168 //printDir("/data"); 1169 char buf[20] = ""; 1170 FILE* f = fopen("/data/.layout_version", "r"); 1171 if (NULL != f) { 1172 fread(buf, 1, sizeof(buf)-1 , f); 1173 LOGW("/data/.layout_version = %s.......\n", buf); 1174 fclose(f); 1175 } 1176 } 1177 ensure_path_unmounted(path); 1178 return 0; 1179 } 1180 1181 extern int getBuilitinList(); 1182 1183 //#Fangfang.Hui@Swdp.Android.Recovery, 2016/05/24, Add for save some last_logs to memory and restore them later when wipe cache 1184 typedef struct _saved_log_file { 1185 char* name; 1186 struct stat st; 1187 unsigned char* data; 1188 struct _saved_log_file* next; 1189 } saved_log_file;
08-19
<think>首先,用户的问题是:在另一个函数中调用了`_poe_auto_recovery_config_set`,现在想删除这个函数,然后把调用改为直接调用`poe_recovery_set_port_config`。具体来说,用户想将`_poe_auto_recovery_config_set(user_port, (void*)&recovery_cfg);`改为`rv = poe_recovery_set_port_config(user_port, const &recovery_cfg, TRUE);`是否合适。 我需要分析代码: - `_poe_auto_recovery_config_set`函数定义: ```c static int _poe_auto_recovery_config_set(int user_port, const POE_PORTRECOVERYCFG_STRUCT* recovery_cfg) { int rv = 0; rv = poe_recovery_set_port_config(user_port, recovery_cfg, TRUE); if (rv != ERR_NO_ERROR) printf("[%s]Set auto recovery port%d failed\n", __FUNCTION__, user_port); return ERR_NO_ERROR; } ``` 这个函数: - 调用`poe_recovery_set_port_config(user_port, recovery_cfg, TRUE)`。 - 检查返回值`rv`,如果不等于`ERR_NO_ERROR`,打印错误消息。 - 最后返回`ERR_NO_ERROR`,无论前面的操作是否出错。这意味着即使设置失败,它也返回成功状态。 - 用户想在调用点将`_poe_auto_recovery_config_set(user_port, (void*)&recovery_cfg);`改为`rv = poe_recovery_set_port_config(user_port, const &recovery_cfg, TRUE);`。 关键点: 1. **原始调用的类型转换**:在调用`_poe_auto_recovery_config_set`时,参数是`(void*)&recovery_cfg)`。`recovery_cfg`可能是指向`POE_PORTRECOVERYCFG_STRUCT`的指针。在`_poe_auto_recovery_config_set`的定义中,第二个参数是`const POE_PORTRECOVERYCFG_STRUCT* recovery_cfg`,所以传递`(void*)`似乎是多余的或不必要的类型转换。这可能是个错误或为了兼容性。 2. **修改后的调用**:用户想改为`poe_recovery_set_port_config(user_port, const &recovery_cfg, TRUE)`。这里有语法错误: - `const &recovery_cfg`:在C语言中,`const &`不是有效的语法。可能应该是`&recovery_cfg`,但`poe_recovery_set_port_config`的原型需要什么类型? - 从`_poe_auto_recovery_config_set`内部调用来看,`poe_recovery_set_port_config`的原型是`int poe_recovery_set_port_config(int user_port, const POE_PORTRECOVERYCFG_STRUCT* recovery_cfg, BOOL flag)`或类似的东西。所以第二个参数应该是指向`POE_PORTRECOVERYCFG_STRUCT`的指针。 - 在调用点,`recovery_cfg`假设是`POE_PORTRECOVERYCFG_STRUCT`类型的变量(因为使用`&recovery_cfg`),所以传递地址是正确的。 - 但用户写的是`const &recovery_cfg`,这看起来像是C++语法。在C语言中,应该只是`&recovery_cfg`,不带`const`关键字在表达式级别。常量性应该在指针类型中处理。 3. **行为变化**: - 原始函数`_poe_auto_recovery_config_set`在调用`poe_recovery_set_port_config`后,如果返回值非零,打印错误消息,但总是返回`ERR_NO_ERROR`。 - 如果直接将调用改为`poe_recovery_set_port_config(...)`,那么: - 没有错误日志打印:失去了错误处理代码。 - 返回值处理:在原始调用中,调用`_poe_auto_recovery_config_set`没有检查其返回值(因为用户只写了`_poe_auto_recovery_config_set(...);`,没有赋值或检查)。用户提供的调用是`_poe_auto_recovery_config_set(user_port, (void*)&recovery_cfg);`,没有赋值,所以返回值被忽略。 - 在新调用中,用户写`rv = poe_recovery_set_port_config(...);`,所以返回值被存储到`rv`,但没有后续错误处理或打印。 4. **合适性**: - 从功能角度看,直接调用`poe_recovery_set_port_config`是可行的,因为它避免了间接层。 - 但是,失去了错误日志:如果`poe_recovery_set_port_config`失败,不再打印错误消息。 - 原始函数总是返回`ERR_NO_ERROR`,忽略实际错误,所以调用者可能不知道失败。 - 在调用点,如果原始调用没有检查返回值,删除这个函数并直接调用可能看起来相同,但错误处理丢失了。 - 类型转换问题:原始调用使用`(void*)&recovery_cfg)`,而`poe_recovery_set_port_config`可能期望`const POE_PORTRECOVERYCFG_STRUCT*`。在C语言中,类型转换可能是不必要的,但如果`recovery_cfg`的类型不匹配,可能需要。用户的新调用写`const &recovery_cfg`,这无效;应该改为`&recovery_cfg`,假设`recovery_cfg`是正确类型的变量。 建议回答: - 语法上,用户的新调用有错误:`const &recovery_cfg`应改为`&recovery_cfg`。 - 功能上,直接调用是合适的,但需要添加错误处理,因为原始函数有打印日志。 - 如果调用者不需要错误处理,并且原函数总是返回成功,那么直接调用可能足够。 - 但最好保留错误日志,或者确保错误被妥善处理。 最终建议:修改调用是可行的,但需要修复语法和考虑添加错误日志。 现在,回答必须用中文。 在回答后,必须提出3-5个相关的问题,以"§§相关问题§§"开头。 问题必须连贯输出,不换行分散。 结构化回答: 1. 直接回答问题是否合适:基本上合适,但有注意事项。 2. 解释原因。 3. 建议修改。 然后输出相关问题。 相关问题基于问题和回答,比如关于函数封装、错误处理、类型转换等。 相关问题的想法: 1. 为什么在C语言中使用包装函数可能会带来好处或缺点? 2. 如何处理函数调用中的错误日志,以确保代码健壮性? 3. 在C语言中,如何正确传递指针参数以避免类型转换警告? 4. 当删除中间函数时,如何确保原有功能完整性? 5. 静态函数在模块化设计中扮演什么角色? 确保3-5个问题。 回答格式: - 先回答问题。 - 然后一行"§§相关问题§§" - 然后1. 2. 3. ... 列表。 完整回答。 </think>针对用户的问题,分析如下代码改动: 原函数定义: ```c static int _poe_auto_recovery_config_set(int user_port, const POE_PORTRECOVERYCFG_STRUCT* recovery_cfg) { int rv = 0; rv = poe_recovery_set_port_config(user_port, recovery_cfg, TRUE); if (rv != ERR_NO_ERROR) printf("[%s]Set auto recovery port%d failed\n", __FUNCTION__, user_port); return ERR_NO_ERROR; } ``` 用户计划在调用点将: ```c _poe_auto_recovery_config_set(user_port, (void*)&recovery_cfg); ``` 改为: ```c rv = poe_recovery_set_port_config(user_port, const &recovery_cfg, TRUE); ``` ### 是否合适? **不完全合适**,主要基于以下原因: 1. **语法错误**:新调用中的 `const &recovery_cfg` 在C语言中无效。正确写法应为 `&recovery_cfg`(省略 `const` 关键字),因为 `poe_recovery_set_port_config` 的第二个参数类型应为 `const POE_PORTRECOVERYCFG_STRUCT*`(即指针),而 `&recovery_cfg` 直接提供地址。原始调用中的 `(void*)` 类型转换可能是不必要的冗余或错误,应移除以避免潜在警告。 2. **功能丢失**:原函数 `_poe_auto_recovery_config_set` 包含错误处理逻辑(若 `poe_recovery_set_port_config` 返回非 `ERR_NO_ERROR`,则打印错误日志)。直接调用 `poe_recovery_set_port_config` 会丢失此日志,可能导致运行时错误被忽略,降低代码可调试性。 3. **返回值处理**:原函数总是返回 `ERR_NO_ERROR`(忽略实际错误),而新调用将返回值赋给 `rv`,但未添加错误检查或日志。如果调用者依赖此返回值(尽管原调用未显式使用),需确保新代码中处理潜在错误。 4. **潜在风险**:如果 `recovery_cfg` 的类型不是 `POE_PORTRECOVERYCFG_STRUCT`,传递 `&recovery_cfg` 可能导致类型不匹配警告或错误(原始 `(void*)` 可能旨在抑制此问题)。建议检查变量类型一致性。 ### 建议修改: 若需删除 `_poe_auto_recovery_config_set`,应将调用改为: ```c int rv = poe_recovery_set_port_config(user_port, &recovery_cfg, TRUE); // 修复语法 if (rv != ERR_NO_ERROR) { printf("[%s]Set auto recovery port%d failed\n", __FUNCTION__, user_port); // 保留错误日志 } ``` 这确保功能完整性和错误处理不丢失。同时,验证 `recovery_cfg` 类型匹配以避免编译问题。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值